home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Medal Software 2
/
Gold Medal Software Volume 2 (Gold Medal) (1994).iso
/
prog
/
asm_0_m.arj
/
FREECOPY.ASM
< prev
next >
Wrap
Assembly Source File
|
1985-06-06
|
94KB
|
2,855 lines
Page 55,132
Title FREECOPY Version 1.13 (C)Copyright 1984
;*********************** F R E E C O P Y ******************************
;* *
;* Program: FREECOPY *
;* *
;* Author: Donald L. Buresh, C.D.P. *
;* Squire Buresh Associates, Inc. *
;* Post Office Box 112 *
;* Millbury, MA 01527 *
;* (617) 865-3435 *
;* *
;* !!!!!!!!!!!!!!!!!!!!!! N O T I C E !!!!!!!!!!!!!!!!!!!!!! *
;* *
;* A limited license is granted to all users of this program to *
;* make copies of this source code and to distribute them to *
;* other users under the following conditions: *
;* *
;* 1. The notice contained in the variable MES00_Copy_Notice *
;* is not to be altered, bypassed or removed. *
;* *
;* 2. The program is not to be distributed to others in *
;* modified form. *
;* *
;* 3. If you think that this program has helped you, we request *
;* a $25.00 contribution. *
;* *
;* 4. No other fee is to be charged or any consideration received *
;* for copying or distributing the program without the *
;* expressed written permission of Squire Buresh Assoc, Inc. *
;* *
;* *
;* (C) Copyright 1984 Squire Buresh Associates, Inc. *
;* *
;************************************************************************
Page
;************************************************************************
;* *
;* REVISION HISTORY *
;* *
;* Version *
;* Number Date Comments *
;* *
;* 1.00 16-SEP-84 This is the first version of FREECOPY *
;* *
;* 1.01 13-OCT-84 Corrected a problem when copying *
;* diskettes on 512K systems. Reversed *
;* the order of testing the ES:BX table *
;* counter and the read/write track *
;* counter. Fix was near C2005, C2006, *
;* C2105 and C2106. *
;* *
;* 1.02 13-OCT-84 Flushed the standard input keyboard *
;* buffer before accepting a character. *
;* Fix was near U1101 and U1102. *
;* *
;* 1.03 21-OCT-84 Added parsing a tab character on the *
;* command line. Fix was below C1215. *
;* *
;* 1.04 - 1.09 These versions never really existed in *
;* any decent form. They are incorporated *
;* into fixing the memory allocation *
;* problems stemming from the original *
;* version of FREECOPY. *
;* *
;* 1.10 02-FEB-85 Allocated and freed memory when running *
;* FREECOPY under PC-DOS versions 2.00 *
;* and greater. The fix involved finding *
;* out the version of the operating system,*
;* allocating the memory, establishing *
;* the ES:BX table entries and freeing *
;* memory before returning control to *
;* PC-DOS. *
;* *
;* 1.11 06-JUN-85 Modified the sequence of turning inter- *
;* rupts on and off in the S1000 and S1100 *
;* modules. *
;* *
;* 1.12 06-JUN-85 Allowed users to write more than one *
;* target diskette, by setting FLG17 to *
;* True and jumping to B1105A after ini- *
;* tializing the appropriate variables. *
;* *
;* 1.13 07-JUN-85 Fixed a stack imbalance that appeared *
;* only when running PC-DOS 3.00 on a PC *
;* rather than on an XT or AT *
;* *
;************************************************************************
Page
;************************************************************************
;* *
;* EQUATES *
;* *
;* The constants defined below are used to to specify: *
;* *
;* o Disk commands, *
;* *
;* o Keyboard commands, *
;* *
;* o Video commands *
;* *
;* o Miscellaneous parameters, *
;* *
;* o Various ASCII characters. *
;* *
;************************************************************************
;
Disk_Parameter_Addr Equ 001EH*4 ; Address of Disk Parameter Table
;
Reset_Command Equ 0000D ; Diskette reset command
Status_Command Equ 0001D ; Diskette status command
Read_Command Equ 0002D ; Diskette read command
Write_Command Equ 0003D ; Diskette write command
Verify_Command Equ 0004D ; Diskette verify command
Format_Command Equ 0005D ; Diskette format command
;
Time_Out_Error Equ 0080H ; Diskette error codes
Seek_Error Equ 0040H ; .
Controller_Error Equ 0020H ; .
CRC_Error Equ 0010H ; .
DMA_Boundary_Error Equ 0009H ; .
DMA_Error Equ 0008H ; .
Sector_Error Equ 0004H ; .
Write_Protect_Error Equ 0003H ; .
Address_Mark_Error Equ 0002H ; .
Command_Error Equ 0001H ; ..End
;
Video_Address Equ 0A000H ; Starting segment addr of Video RAM
;
Set_Mode_Command Equ 0000D ; Set the video mode
Set_CType_Command Equ 0001D ; Set the cursor type
Set_CPos_Command Equ 0002D ; Set the cursor position
Read_Cursor_Command Equ 0003D ; Get cursor position and attributes
Read_LPen_Command Equ 0004D ; Get the light pen position
Set_ADPage_Command Equ 0005D ; Set the active display page
Scroll_Up_Command Equ 0006D ; Scrool up or blank a portion of
; . the video display
;
Page
;************************************************************************
;* *
;* EQUATES Page 2 *
;* *
;************************************************************************
;
Scroll_Down_Command Equ 0007D ; Scroll down or blank a portion
; . of the video display
Read_AChar_Command Equ 0008D ; Read the attribute and character
Write_AChar_command Equ 0009D ; Write the attribute and character
Write_Char_Command Equ 0010D ; Write the character only
Set_Color_Command Equ 0011D ; Set the color pallette
Write_Dot_Command Equ 0012D ; Write a pixel to a graphics screen
Read_Dot_Command Equ 0013D ; Read a pixel from a graphics screen
Write_TTY_Command Equ 0014D ; Write a character with automatic
; . processing for LF, CR, Bell & BS
Video_State_Command Equ 0015D ; Get the current video state
;
Read_Keyboard_Command Equ 0007D ; Reads character from the keyboard
Flush_Keyboard_Command Equ 0012D ; Clears the standard keyboard buffer
Get_DOS_Version_Number Equ 0030H ; Gets the current version of PC-DOS
Allocate_Memory Equ 0048H ; Allocate a block of memory
Free_Memory Equ 0049H ; Free a block of memory
Modify_Memory_Block Equ 004AH ; Modify the size of memory block
;
Default_Drive_Command Equ 0025D ; Get PC DOS default drive number
;
Video_Interrupt Equ 0010H ; Interrupt 10H for video calls
Equipment_Interrupt Equ 0011H ; Interrupt 11H for equipment
Disk_Interrupt Equ 0013H ; Interrupt 13H for disk calls
PC_DOS_Interrupt Equ 0021H ; Interrupt 21H for PC DOS calls
;
Parallel_Ports_Mask Equ 0C000H ; Equipment masks
Game_Adapters_Mask Equ 00100H ; .
RS232_Ports_Mask Equ 00E00H ; .
Disk_Drives_Mask Equ 000C0H ; .
Init_Video_Mask Equ 00030H ; .
Planar_RAM_Mask Equ 0000CH ; .
IPL_Diskette_Mask Equ 00001H ; ..End
;
Page
;************************************************************************
;* *
;* EQUATES Page 3 *
;* *
;************************************************************************
;
Command_Com_Size Equ 0410D ; Size of various tables and programs
CHRN_Table_Size Equ 0180D ; in 16 byte paragraphs
; .
; .
ESBX_Table_Size Equ 0020D ; .
; .
; .
FAT_Sector_Size Equ 0032D ; ..End
;
DMA_Boundary_Mask Equ 0FFFH ; Mask to isolate the high nibble of
; . the ES segment address
;
Invalid_Drive Equ 0255D ; Invalid drive parameter
Maximum_Drives Equ 0003D ; Maximum number of floppy drives
Minimum_Drives Equ 0000D ; Minimum number of floppy drives
;
Sector_Size Equ 0512D ; Number of bytes per sector
Paragraph_Size Equ 0016D ; Number of bytes per paragraph
Number_of_Retries Equ 0005D ; Number of attempts to copy
; . a track before admitting failure
Final_Track Equ 0039D ; The last track on a PC DOS diskette
;
One_Side_Eight_Sectors Equ 00FEH ; First entry in the File Allocation
Two_Sides_Eight_Sectors Equ 00FFH ; Table (FAT)
One_Side_Nine_Sectors Equ 00FCH ; .
Two_Sides_Nine_Sectors Equ 00FDH ; .
Fixed_Disk Equ 00F8H ; ..End
;
Keyboard_Buffer_Size Equ 0080D ; Maximum number of characters in
; . the keyboard buffer
;
Minimum_Memory_Size Equ 0288D ; Minimum memory size in 16 byte
; . paragraphs to hold a nine
; . sectored track
;
Blank_Cursor Equ 0F0FH ; Blank cursor value
Underline_Cursor Equ 0D0DH ; Underline cursor value
;
False Equ 0000D ; Incorrect processing occured
True Equ Not False ; Correct processing occured
High_Values Equ 0FFFFH ; High values
;
Page
;************************************************************************
;* *
;* EQUATES Page 4 *
;* *
;************************************************************************
;
NUL Equ 0000D ; Null character
SOH Equ 0001D ; SOH character
STX Equ 0002D ; STX character
ETX Equ 0003D ; Control Break character
Bell Equ 0007D ; Bell character
BS Equ 0008D ; Backspace character
HT Equ 0009D ; Horizontal tab character
LF Equ 0010D ; Line feed character
CR Equ 0013D ; Carriage return character
Space Equ 0032D ; Space or blank character
Slash Equ 0047D ; Slash character
Zero_Digit Equ 0048D ; Digit Zero
One_Digit Equ 0049D ; Digit One
Capital_Letter_A Equ 0065D ; Capital letter A
Capital_Letter_N Equ 0078D ; Capital letter N
Capital_Letter_Y Equ 0089D ; Capital letter Y
Small_Letter_n Equ 0110D ; Small letter n
Small_Letter_y Equ 0121D ; Small letter y
EOT Equ 0255D ; End of text character
;
Minus_One Equ -1D ; Numbers used in FREECOPY
Zero Equ 0000D ; .
One Equ 0001D ; .
Two Equ 0002D ; .
Three Equ 0003D ; .
Four Equ 0004D ; .
Six Equ 0006D ; .
Eight Equ 0008D ; .
Nine Equ 0009D ; .
Ten Equ 0010D ; .
Eleven Equ 0011D ; .
Twelve Equ 0012D ; .
Fourteen Equ 0014D ;.
Fifteen Equ 0015D ; .
Twenty_Four Equ 0024D ; .
Twenty_Five Equ 0025D ; .
Thirty_Four Equ 0034D ; .
Thirty_Six Equ 0036D ; .
Thirty_Nine Equ 0039D ; .
Seventy_Nine Equ 0079D ; ..End
;
Page
;************************************************************************
;* *
;* CSEG Segment *
;* *
;* This segment contains all of the code of the program. It is *
;* named CSEG because this name conforms with ASM-86. *
;* *
;************************************************************************
;
CSEG Segment Para Public 'CSEG'
Assume CS:CSEG,DS:CSEG,ES:CSEG,SS:Nothing
;
Page
;************************************************************************
;* *
;* PROGRAM SEGMENT PREFIX *
;* *
;* The first 256 bytes of every program executed under PC DOS *
;* contains a Program Segment Prefix control block. The data *
;* stored in this block of memory is used by FREECOPY to process *
;* the parameters when invoking the program. *
;* *
;************************************************************************
;
Org 05CH
Source_Drive Label Byte ; Source diskette drive number
Org 05DH
Source_Filename Label Byte ; Source diskette filename
Org 068H
Source_Filler_Area Label Byte
Org 06CH
Target_Drive Label Byte ; Target diskette drive number
Org 06DH
Target_Filename Label Byte ; Target diskette filename
Org 078H
Target_Filler_Area Label Byte
Org 080H
Parameter_Count Label Byte ; Number of parameters
Org 081H
Parameter_String Label Byte ; String entered by the user
;
Page
;************************************************************************
;* *
;* A1000_MAIN_MODULE *
;* *
;* This is the top level of FREECOPY and it controls the flow of *
;* the program. The first sequence of commands in the routine *
;* preserve the state of the machine. Next, there is a set of *
;* three (3) calls to sub-modules that control the initial *
;* processing, detail processing and final processing. Finally, *
;* FREECOPY restores the state of the machine an returns to *
;* PC DOS via INT 20H. *
;* *
;************************************************************************
;
Org 0100H
;
Public A1000_Main_Module
;
A1000_Main_Module Proc Far
;
A1001:
Cli ; Set up the top of the stack
Mov SP,Offset MEM04_Top_of_the_Stack
Sti ; ..End
;
Push BP ; Save the state of the machine
Push DS ; .
Push ES ; .
Push SS ; .
Push AX ; .
Push BX ; .
Push CX ; .
Push DX ; .
Push SI ; .
Push DI ; .
Pushf ; ..End
;
Cli ; Save the current stack pointer
Mov Word Ptr SYS15_Stack_Pointer,SP
Add Word Ptr SYS15_Stack_Pointer,Two ; .
Sti ; ..End
;
Call B1000_Initial_Process ; Main flow of control
Cmp Byte Ptr FLG01_Good_Command,False
Je A1002 ; .
Cmp Byte Ptr FLG03_Default_Drive,False
Je A1002 ; .
Call B1100_Detail_Process ; .
A1002: ; .
Call B1200_Final_Process ; ..End
A1090:
Popf ; Restore the state of the machine
Pop DI ; .
Pop SI ; .
Pop DX ; .
Pop CX ; .
Pop BX ; .
Pop AX ; .
Pop SS ; .
Pop ES ; .
Pop DS ; .
Pop BP ; ..End
A1099:
Int 20H ; Return to PC DOS
;
A1000_Main_Module Endp
;
Page
;************************************************************************
;* *
;* B1000_INITIAL_PROCESS *
;* *
;* This module performs the following functions after control *
;* passess to FREECOPY: *
;* *
;* 1. Sets up the Disk Parameter Table. *
;* *
;* 2. Gets the current PC-DOS version number. *
;* *
;* 3. Initializes various parameters. *
;* *
;* 4. Gets and sets the video mode. *
;* *
;* 5. Displays the intiial message. *
;* *
;* 6. Parses the command line entered by a user. *
;* *
;* 7. Determines the amount of equipment on the machine. *
;* *
;* 8. Validates the number of disk drives on the system. *
;* *
;* 9. Displays the appropriate disk copying message. *
;* *
;* 10. Gets the amount of available memory. *
;* *
;* 11. Calculates the number and position of the entries in the *
;* ES:BX buffer address table. *
;* *
;************************************************************************
;
Page
;
Public B1000_Initial_Process
;
B1000_Initial_Process Proc Near
;
B1001:
Call S1000_Setup_Disk_Param_Table
Call S1200_Get_Version_Number
;
Mov Byte Ptr FLG01_Good_Command,True
Mov Byte Ptr FLG02_Double_Side,True
Mov Byte Ptr FLG03_Default_Drive,True
Mov Byte Ptr FLG04_Single_Drive,True
Mov Byte Ptr FLG07_First_Time,True
Mov Byte Ptr FLG16_Free_Memory,True
Mov Byte Ptr FLG17_Copy_More_Disks,False
B1002:
Call C1000_Get_And_Set_Video ; Get and set current video state
Call C1100_Display_Intro ; Display the intial screen
Call C1200_Parse_Commands ; Parse the command line entered
; . by the user
Cmp Byte Ptr FLG01_Good_Command,False
Je B1099 ; If false, go to end of the module
Call C1300_Get_Equipment ; Find out the equipment on the PC
Call C1400_Validate_Drives ; Validate the drive numbers
Cmp Byte Ptr FLG03_Default_Drive,False
Je B1099 ; If false, go to end of the module
Call C1500_Diskette_Messages ; Display the appropriate messages
;
Cmp Byte Ptr SYS19_Major_Vers_Number,Zero
Jne B1003 ; Get available memory in paragraphs
Call C1600A_Get_Free_Memory ; . and create the ES:BX table
Jmp B1004 ; .
B1003: ; .
Call C1600B_Get_Free_Memory ; .
B1004: ; .
Cmp Byte Ptr FLG01_Good_Command,False
Je B1099 ; .
Call C1700_Create_ESBX_Table; ..End
B1099:
Ret
;
B1000_Initial_Process Endp
;
Page
;************************************************************************
;* *
;* B1100_DETAIL_PROCESS *
;* *
;* This module performs the following functions when copying one *
;* or more diskettes: *
;* *
;* 1. Initializes various parameters. *
;* *
;* 2. Validates the contents of the source diskette. *
;* *
;* 3. Creates all of the entries of the CHRN table used in *
;* formatting the target diskette. *
;* *
;* 4. Reads the tracks of the source diskette. *
;* *
;* 5. If the diskette is being copied on only one drive, the *
;* routines asks the user to enter the target diskette. *
;* *
;* 6. Writes the tracks on the target diskette. *
;* *
;* 7. If FREECOPY is finished copying the source diskette, the *
;* program asks whether to write another target diskette, *
;* provided the source diskette fits completely in memory; *
;* otherwise, the program asks whether to copy a new diskette. *
;* If not, the module returns to A1000_Main_Module. If so, *
;* control transfers to 1. *
;* *
;* 8. If FREECOPY is not completed copying the source diskette, *
;* control transfers to 4. *
;* *
;************************************************************************
;
Page
;
Public B1100_Detail_Process
;
B1100_Detail_Process Proc Near
;
B1101:
Mov Byte Ptr WRK20_Current_Source_Head,Zero
Mov Byte Ptr WRK21_Current_Source_Track,Zero
Mov Byte Ptr WRK22_Current_Target_Head,Zero
Mov Byte Ptr WRK23_Current_Target_Track,Zero
Mov Word Ptr WRK33_CHRN_Table_Address,Offset MEM02_CHRN_Table
Mov Byte Ptr FLG13_First_Read_Write,True
Mov Byte Ptr FLG14_Copy_Complete,False
Mov Byte Ptr FLG15_IO_Error,Three
B1102:
Call C1800_Validate_Source_Disk
Cmp Byte Ptr FLG08_Good_Read,True
Je B1103 ; If it is a valid source, continue
Mov SI,Offset MES07_Correct_And_Press_Key
Call U1000_Display_Message ; Display the message on the screen
Mov Byte Ptr FLG05_Store_Buffer,False
Call U1100_Get_Response ; Get the user's response
Jmp B1101 ; Go back and try again
B1103:
Call C1900_Create_CHRN_Table
B1104:
Call C2000_Read_Source_Disk
Cmp Byte Ptr FLG08_Good_Read,True
Je B1105 ; If read disk correctly, continue
Mov SI,Offset MES07_Correct_And_Press_Key
Call U1000_Display_Message ; Display the message on the screen
Mov Byte Ptr FLG05_Store_Buffer,False
Call U1100_Get_Response ; Get the user's response
Jmp B1101 ; Go back and try again
B1105:
Cmp Byte Ptr FLG04_Single_Drive,False
Je B1106 ; If a single drive copy, continue
B1105A:
Mov SI,Offset MES10_Insert_Target
Mov AL,Byte Ptr WRK02_Target_Drive
Add AL,Capital_Letter_A ; Put drive letter into AL
Mov [SI+Thirty_Four],AL ; Put the drive letter into the
; . correct position in the message
Call U1000_Display_Message ; Display the message on the screen
Mov SI,Offset MES16_Press_Any_Key
Call U1000_Display_Message ; Display the message on the screen
Mov Byte Ptr FLG05_Store_Buffer,False
Call U1100_Get_Response ; Get the user's response
B1106:
Call C2100_Write_Format_Target_Disk
Cmp Byte Ptr FLG09_Good_Write,False
Je B1110 ; If bad write, go to bottom of loop
Cmp Byte Ptr FLG11_Good_Format,False
Je B1110 ; If bad format, go to bottom of loop
B1107:
Cmp Byte Ptr FLG14_Copy_Complete,True
Je B1109 ; If copy done, go to bottom of loop
Cmp Byte Ptr FLG04_Single_Drive,False
Je B1108 ; If double drive copy, continue
Mov SI,Offset MES09_Insert_Source
Mov AL,Byte Ptr WRK01_Source_Drive
Add AL,Capital_Letter_A ; Put the drive letter into AL
Mov [SI+Thirty_Four],AL ; Put the drive letter into the
; . correct position in the message
Call U1000_Display_Message ; Display the message on the screen
Mov SI,Offset MES16_Press_Any_Key
Call U1000_Display_Message ; Display the message on the screen
Mov Byte Ptr FLG05_Store_Buffer,False
Call U1100_Get_Response ; Get the user's response
B1108:
Call C2200_Check_File_Alloc_Table
Cmp Byte Ptr FLG12_Good_FAT,False
Je B1110 ; If bad FAT, go to bottom of loop
Mov Byte Ptr FLG13_First_Read_Write,False
Jmp B1104 ; Go back and read some more
B1109:
Mov Byte Ptr FLG07_First_Time,False
Mov SI,Offset MES02_Copy_Complete
Call U1000_Display_Message
B1110:
Cmp Byte Ptr FLG17_Copy_More_Disks,False
Je B1111
Mov SI,Offset MES01A_Write_Another_Diskette
Call U1000_Display_Message
Call U1200_Get_Yes_or_No
Cmp Byte Ptr FLG06_Yes_or_No,False
Je B1111 ; Continue
Mov Byte Ptr WRK22_Current_Target_Head,Zero
Mov Byte Ptr WRK23_Current_Target_Track,Zero
Mov Word Ptr WRK33_CHRN_Table_Address,Offset MEM02_CHRN_Table
Mov Byte Ptr FLG13_First_Read_Write,True
Mov Byte Ptr FLG14_Copy_Complete,False
Mov Byte Ptr FLG15_IO_Error,Three
Jmp B1105A ; Start writing a diskette again
B1111:
Mov SI,Offset MES01B_Copy_Another_Diskette
Call U1000_Display_Message
Call U1200_Get_Yes_or_No
Cmp Byte Ptr FLG06_Yes_or_No,False
Je B1199 ; Go to the end of the module
Call C1500_Diskette_Messages ; Print out the messages on screen
Jmp B1101 ; Start copying a diskette again
B1199:
Ret
;
B1100_Detail_Process Endp
;
Page
;************************************************************************
;* *
;* B1200_FINAL_PROCESS *
;* *
;* This module performs the following functions before returning *
;* control to PC DOS: *
;* *
;* 1. Restores the value of the stack pointer. *
;* *
;* 2. Displays the final message of the program. *
;* *
;* 3. Restores the underline cursor. *
;* *
;* 4. Restores the settings in the Disk Parameter Table. *
;* *
;* 5. Returns control to A1000_Main_Module. *
;* *
;************************************************************************
;
Page
;
Public B1200_Final_Process
;
B1200_Final_Process Proc Near
;
B1201:
Cli ; Establish the stack pointer
Mov SP,Word Ptr SYS15_Stack_Pointer
Sti ; ..End
;
Call C2300_Free_Memory ; Free allocated memory if necessary
;
Mov SI,Offset MES100_Freecopy_Finished
Call U1000_Display_Message ; Display the message on the screen
;
Mov AH,Set_CType_Command ; Restore the underline cursor
Mov CX,Underline_Cursor ; .
Int Video_Interrupt ; ..End
;
Call S1100_Restore_Disk_Param_Table
;
Mov AX,Offset A1090 ; Setup to return to the main module
Push CS ; .
Push AX ; ..End
B1299:
Ret
;
B1200_Final_Process Endp
;
Page
;************************************************************************
;* *
;* C1000_GET_AND_SET_VIDEO *
;* *
;* This module gets the current video state and saves this *
;* information in the various SYStem variables. *
;* *
;************************************************************************
;
Public C1000_Get_And_Set_Video
;
C1000_Get_And_Set_Video Proc Near
;
C1001:
Push AX ; Save the registers
Push BX ; .
Push CX ; ..End
C1002:
Mov AH,Video_State_Command ; Get the current video state
Int Video_Interrupt ; ..End
Mov Byte Ptr SYS01_Number_Columns,AH
Mov Byte Ptr SYS02_Current_Mode,AL
Mov Byte Ptr SYS03_Active_Page,BH
C1003:
Mov AH,Set_CType_Command ; Set the cursor to blanks
Mov CX,Blank_Cursor ; .
Int Video_Interrupt ; ..End
C1090:
Pop CX ; Restore the registers
Pop BX ; .
Pop AX ; ..End
C1099:
Ret
;
C1000_Get_And_Set_Video Endp
;
Page
;************************************************************************
;* *
;* C1100_DISPLAY_INTRO *
;* *
;* This module displays the introductory message to FREECOPY. *
;* Please do not disable this message, since it states the *
;* conditions under which a person may copy this program. *
;* *
;************************************************************************
;
Public C1100_Display_Intro
;
C1100_Display_Intro Proc Near
;
C1101:
Mov SI,Offset MES00_Copy_Notice ; Display the copy notice
Call U1000_Display_Message ; ..End
C1199:
Ret
C1100_Display_Intro Endp
;
Page
;************************************************************************
;* *
;* C1200_PARSE_COMMANDS *
;* *
;* This module parses the command line entered by the user *
;* by checking the following conditions: *
;* *
;* 1. The source and/or the target drives do not exist. *
;* *
;* 2. The command line contains any characters other than two *
;* drive letters (e.g., a filename). *
;* *
;* 3. The /1 (single side) parameter is on the command line. *
;* *
;************************************************************************
;
Public C1200_Parse_Commands
;
C1200_Parse_Commands Proc Near
;
C1201:
Cmp AH,Invalid_Drive ; Compare for invalid drive parms
Jne C1202 ; .
Mov Byte Ptr FLG01_Good_Command,False
Mov SI,Offset MES14_Invalid_Drive
Call U1000_Display_Message
Jmp C1299 ; .
C1202: ; .
Cmp AL,Invalid_Drive ; .
Jne C1203 ; .
Mov Byte Ptr FLG01_Good_Command,False
Mov SI,Offset MES14_Invalid_Drive
Call U1000_Display_Message
Jmp C1299 ; ..End
C1203:
Mov AL,Byte Ptr Source_Drive
Mov Byte Ptr WRK01_Source_Drive,AL
Mov AL,Byte Ptr Target_Drive
Mov Byte Ptr WRK02_Target_Drive,AL
C1204:
Mov SI,Offset Source_Filename
Mov DI,Offset WRK03_Valid_Filename
Mov CX,Eleven ; Set CX to compare 11 characters
C1205:
Mov AL,[SI] ; Compare for valid source diskette
Mov AH,[DI] ; filename in the FCB at 05DH
Cmp AH,AL ; .
Je C1206 ; .
Mov Byte Ptr FLG01_Good_Command,False
Mov SI,Offset MES12_Invalid_Parameter
Call U1000_Display_Message
Jmp C1299 ; .
C1206: ; .
Inc SI ; .
Inc DI ; .
Loop C1205 ; ..End
C1207:
Mov SI,Offset Target_Filename
Mov DI,Offset WRK03_Valid_Filename
Mov CX,Eleven ; Set CX to comapre 11 characters
C1208:
Mov AL,[SI] ; Compare for valid target diskette
Mov AH,[DI] ; . filename in the FCB at 06DH
Cmp AH,AL ; .
Je C1209 ; .
Mov Byte Ptr FLG01_Good_Command,False
Mov SI,Offset MES12_Invalid_Parameter
Call U1000_Display_Message
Jmp C1299 ; .
C1209: ; .
Inc SI ; .
Inc DI ; .
Loop C1208 ; ..End
C1210:
Mov AL,Byte Ptr Parameter_Count
Mov Byte Ptr WRK04_Parameter_Count,AL
Mov SI,Offset Parameter_String
Inc Byte Ptr WRK04_Parameter_Count
C1211:
Dec Byte Ptr WRK04_Parameter_Count
Jz C1299 ; Go to the end of the module
Mov AL,[SI] ; Put the character into AL
Cmp AL,Slash ; Compare character with a slash
Je C1212 ; If so, then continue processing
Inc SI ; Increment the command string addr
Jmp C1211 ; Go back and try again
C1212:
Inc SI ; Increment the command string addr
Mov AL,[SI] ; Get the next char after the slash
Cmp AL,One_Digit ; Compare with the char 1
Je C1214 ; Set double side flag to false
C1213:
Mov Byte Ptr FLG01_Good_Command,False
Mov SI,Offset MES12_Invalid_Parameter
Call U1000_Display_Message
Jmp C1299 ; Go to the end of the module
C1214:
Mov Byte Ptr FLG02_Double_Side,False
Dec Byte Ptr WRK04_Parameter_Count
Jz C1299 ; Go to the end of the module
C1215:
Dec Byte Ptr WRK04_Parameter_Count
Jz C1299 ; Go to the end of the module
Inc SI ; Increment the command string addr
Mov AL,[SI] ; Get the next char in command line
Cmp AL,HT ; Check for tabs and spaces
Je C1215 ; .
Cmp AL,Space ; .
Je C1215 ; ..End
C1216:
Mov Byte Ptr FLG01_Good_Command,False
Mov SI,Offset MES12_Invalid_Parameter
Call U1000_Display_Message
C1299:
Ret
;
C1200_Parse_Commands Endp
;
Page
;************************************************************************
;* *
;* C1300_GET_EQUIPMENT *
;* *
;* This module determines the peripheral devices on the machine. *
;* It invokes the equipment status interrupt and places the *
;* information into the appropriate SYStem parameters. *
;* *
;************************************************************************
;
Public C1300_Get_Equipment
C1300_Get_Equipment Proc Near
;
C1301:
Int Equipment_Interrupt ; Get the equipment on machine
Mov BX,AX ; Save the result for future use
;
And AX,Parallel_Ports_Mask ; Get the number of parallel ports
Mov CL,Fourteen ; .
Shr AX,CL ; .
Mov Byte Ptr SYS07_No_Parallel_Ports,AL
;
Mov AX,BX ; Get the game adapter attachments
And AX,Game_Adapters_Mask ; .
Mov CL,Twelve ; .
Shr AX,CL ; .
Mov Byte Ptr SYS08_Game_Adapters,AL
;
Mov AX,BX ; Get the number of RS-232 ports
And AX,RS232_Ports_Mask ; .
Mov CL,Nine ; .
Shr AX,CL ; .
Mov Byte Ptr SYS09_No_RS232_Ports,AL
;
Mov AX,BX ; Get the number of diskette drives
And AX,Disk_Drives_Mask ; .
Mov CL,Six ; .
Shr AX,CL ; .
Mov Byte Ptr SYS10_No_Disk_Drives,AL
;
Mov AX,BX ; Get the initial video mode
And AX,Init_Video_Mask ; .
Mov CL,Four ; .
Shr AX,CL ; .
Mov Byte Ptr SYS11_Init_Video_Mode,AL
;
Mov AX,BX ; Get planar RAM size
And AX,Planar_RAM_Mask ; .
Mov CL,Two ; .
Shr AX,CL ; .
Mov Byte Ptr SYS12_Planar_RAM_Size,AL
;
Mov AX,BX ; Get IPL from diskette flag
And AX,IPL_Diskette_Mask ; .
Mov Byte Ptr SYS13_IPL_From_Diskette,AL
;
C1399:
Ret
;
C1300_Get_Equipment Endp
;
Page
;************************************************************************
;* *
;* C1400_VALIDATE_DRIVES *
;* *
;* This module determines if the drives specified in the *
;* command line are floppy disk drives or RAM disk drives. *
;* It also checks if copying the source diskette takes place *
;* on a single drive. *
;* *
;************************************************************************
;
Public C1400_Validate_Drives
;
C1400_Validate_Drives Proc Near
;
C1401:
Mov AH,Default_Drive_Command; Get the PC DOS default drive
Int PC_DOS_Interrupt ; .
Mov Byte Ptr SYS14_Default_Drive,AL
C1402:
Cmp Byte Ptr SYS10_No_Disk_Drives,Minimum_Drives
Ja C1403 ; If not single drive copy, set
; . FLG04 to false
Mov Byte Ptr SYS14_Default_Drive,Minimum_Drives
Mov Byte Ptr WRK01_Source_Drive,Minimum_Drives
Mov Byte Ptr WRK02_Target_Drive,Minimum_Drives
Jmp C1499 ; Go to the end of the module
C1403:
Mov Byte Ptr FLG04_Single_Drive,False
C1404:
Cmp Byte Ptr SYS14_Default_Drive,Maximum_Drives
Jbe C1405 ; If below maximum, continue
Mov Byte Ptr FLG03_Default_Drive,False
Mov SI,Offset MES13_Invalid_Default
Call U1000_Display_Message
Jmp C1499 ; Go to the end of the module
C1405:
Dec Byte Ptr WRK01_Source_Drive
Cmp Byte Ptr WRK01_Source_Drive,Minus_One
Jne C1406
Mov AL,Byte Ptr SYS14_Default_Drive
Mov Byte Ptr WRK01_Source_Drive,AL
C1406:
Dec Byte Ptr WRK02_Target_Drive
Cmp Byte Ptr WRK02_Target_Drive,Minus_One
Jne C1407
Mov AL,Byte Ptr SYS14_Default_Drive
Mov Byte Ptr WRK02_Target_Drive,AL
C1407:
Mov AL,Byte Ptr WRK01_Source_Drive
Mov AH,Byte Ptr WRK02_Target_Drive
Cmp AH,AL ; Check source drive = target drive
Jne C1499 ; If so, then continue
Mov Byte Ptr FLG04_Single_Drive,True
C1499:
Ret
;
C1400_Validate_Drives Endp
;
Page
;************************************************************************
;* *
;* C1500_DISKETTE_MESSAGES *
;* *
;* This module displays the appropriate source and target *
;* insertion diskette messages on the screen. *
;* *
;************************************************************************
;
Public C1500_Diskette_Messages
;
C1500_Diskette_Messages Proc Near
;
C1501:
Cmp Byte Ptr FLG07_First_Time,False
Je C1502 ; If not first time, continue
Cmp Byte Ptr FLG04_Single_Drive,False
Je C1502 ; If false, then continue
Mov SI,Offset MES15_Single_Drive_Copy
Call U1000_Display_Message
C1502:
Mov SI,Offset MES09_Insert_Source
Mov AL,Byte Ptr WRK01_Source_Drive
Add AL,Capital_Letter_A ; Put the drive letter into AL
Mov [SI+Thirty_Four],AL ; Put the drive letter into the
; . correct position in the message
Call U1000_Display_Message ; Display the message on the screen
C1503:
Cmp Byte Ptr FLG04_Single_Drive,True
Je C1505 ; If true, go to the message to press
; . any key to continue
C1504:
Mov SI,Offset MES10_Insert_Target
Mov AL,Byte Ptr WRK02_Target_Drive
Add AL,Capital_Letter_A ; Put the drive letter into AL
Mov [SI+Thirty_Four],AL ; Put the drive letter into the
; . correct position in the message
Call U1000_Display_Message ; Display the message on the screen
C1505:
Mov SI,Offset MES16_Press_Any_Key
Call U1000_Display_Message
Mov Byte Ptr FLG05_Store_Buffer,False
Call U1100_Get_Response
C1599:
Ret
;
C1500_Diskette_Messages Endp
;
Page
;************************************************************************
;* *
;* C1600A_GET_FREE_MEMORY *
;* *
;* This module calculates the amount of free 16 byte paragraphs *
;* available on the machine. The segment address of the beginning *
;* of free memory is obtained by setting DX to: *
;* *
;* 1. The contents of the stack segment SS plus *
;* *
;* 2. 256 bytes for the Program Segment Prefix plus *
;* *
;* 3. 128 bytes for the stack. *
;* *
;* After saving the ES segment register on the stack and *
;* initializing both the offset register BX and the 16 byte *
;* counter register CX to zero, the routine begins the looping *
;* through memory 16 bytes at a time (incrementing the segment *
;* register ES by one) until either the module encounters one *
;* of the two (2) conditions: *
;* *
;* 1. The beginning of Video RAM at the segment address *
;* specified in Video_Address. *
;* *
;* 2. The memory pattern defined by the machine that *
;* indicates no more memory. *
;* *
;* When either of these two (2) conditions occur, CX contains *
;* the number of 16 bytes paragraphs of free memory. *
;* *
;* Since we do not know the size of the transient portion of *
;* COMMAND.COM, FREECOPY makes the worst case assumption that *
;* all of the bytes in COMMAND.COM reside in high memory. *
;* *
;* This module also allocates space for the ES:BX table, the *
;* CHRN table, the File Allocation Table (FAT) of the source *
;* diskette and at least one track (4608 bytes). *
;* *
;* This module executes only when running PC-DOS 1.0 and 1.1!!! *
;* *
;************************************************************************
;
Page
;
Public C1600A_Get_Free_Memory
;
C1600A_Get_Free_Memory Proc Near
;
C1601A:
Mov DX,SS ; Calculate the segment address for
; . the beginning of free memory
Add DX,Offset MEM04_Top_of_the_Stack
;
Push ES ; Save ES on the stack for a moment
Mov BX,NUL ; Initialize BX and CX registers
Mov CX,NUL ; ..End
C1602A:
Mov ES,DX ; Set ES to the appropriate value
Cli ; Turn off interrupts for a moment
Mov AX,ES:[BX] ; Read a word from memory into AX
Mov Word Ptr ES:[BX],SOH ; Put the test pattern into memory
Cmp Word Ptr ES:[BX],SOH ; Compare memory with test pattern
Mov ES:[BX],AX ; Restore the contents of memory
Sti ; Turn on the interrupts
Jne C1603A ; If not equal, stop looping
Inc DX ; Increment DX segment register
Cmp DX,Video_Address ; Compare for start of Video RAM
Jae C1603A ; If so, stop looping
Inc CX ; Increment 16 byte counter CX
Jmp C1602A ; Go back and try again
C1603A:
Pop ES ; Restore the ES register
Cmp CX,Command_Com_Size ; Compare the paragraph size of
; . free memory with the paragraph
; . size of COMMAND.COM.
Ja C1604A ; If greater, continue
;
Mov Byte Ptr FLG01_Good_Command,False
Mov SI,Offset MES11_Insufficient_Memory
Call U1000_Display_Message ; Display the message on the screen
Jmp C1699A ; Go to the end of the module
C1604A:
Sub CX,Command_Com_Size ; Subtract the size of COMMAND.COM
Cmp CX,ESBX_Table_Size ; Compare the paragraph size of the
; . free memory with the paragraph
; . size of the ES:BX table
Ja C1605A ; If greater, continue
Mov Byte Ptr FLG01_Good_Command,False
Mov SI,Offset MES11_Insufficient_Memory
Call U1000_Display_Message ; Display the message on the screen
Jmp C1699A ; Go to the end of the module
C1605A:
Sub CX,ESBX_Table_Size ; Subtract the size of ES:BX table
Cmp CX,CHRN_Table_Size ; Compare the paragraph size of the
; . free memory with the paragraph
; . size of the CHRN table
Ja C1606A ; If greater, continue
;
Mov Byte Ptr FLG01_Good_Command,False
Mov SI,Offset MES11_Insufficient_Memory
Call U1000_Display_Message ; Display the message on the screen
Jmp C1699A ; Go to the end of the module
C1606A:
Sub CX,CHRN_Table_Size ; Subtract the size of CHRN Table
Cmp CX,FAT_Sector_Size ; Determine if there is enough memory
Jae C1607A ; to read the File Allocation Table
Mov Byte Ptr FLG01_Good_Command,False
Mov SI,Offset MES11_Insufficient_Memory
Call U1000_Display_Message ; Display the message on the screen
Jmp C1699A ; Go to the end of the module
C1607A:
Sub CX,FAT_Sector_Size ; Subtract the size of the source FAT
Cmp CX,Minimum_Memory_Size ; Determine if the amount of memory
Jae C1608A ; can hold a nine sectored track
;
Mov Byte Ptr FLG01_Good_Command,False
Mov SI,Offset MES11_Insufficient_Memory
Call U1000_Display_Message ; Display the message on the screen
Jmp C1699A ; Go to the end of the module
C1608A:
Mov Word Ptr SYS05_Para_RAM_Size,CX
C1699A:
Ret
;
C1600A_Get_Free_Memory Endp
;
Page
;************************************************************************
;* *
;* C1600B_GET_FREE_MEMORY *
;* *
;* This module calcules the amount of available memory. It *
;* executes when running PC-DOS versions 2.0 and above. *
;* *
;************************************************************************
;
Public C1600B_Get_Free_Memory
;
C1600B_Get_Free_Memory Proc Near
;
C1601B:
Mov AH,Modify_Memory_Block ; Allocate enough space for the
Mov BX,Offset MEM00_Bottom_Free_Memory
Mov CL,Four ; . program and all tables
Shr BX,CL ; .
Inc BX ; .
Int PC_DOS_Interrupt ; .
Jnc C1603B ; ..End
C1602B:
Mov Byte Ptr FLG01_Good_Command,False
Mov SI,Offset MES11_Insufficient_Memory
Call U1000_Display_Message ; Display the message on the screen
Jmp C1699B ; Go to the end of the module
C1603B:
Mov AH,Allocate_Memory ; Get the amount of available memory
Mov BX,High_Values ; .
Int PC_DOS_Interrupt ; .
Mov Word Ptr SYS21_Alloc_Segment,AX
Mov Word Ptr SYS05_Para_RAM_Size,BX
Jnc C1699B ; .
Cmp AL,Eight ; .
Je C1605B ; .
C1604B:
Mov SI,Offset MES97_Return_Linefeed
Call U1000_Display_Message ; Issue a carriage return/linefeed
Mov SI,Offset MES99_Memory_Block_Destroyed
Call U1000_Display_Message ; Display the message on the screen
Jmp C1699B ; Go to the end of the module
C1605B:
Mov AH,Allocate_Memory ; .
Int PC_DOS_Interrupt ; ..End
Mov Word Ptr SYS21_Alloc_Segment,AX
Mov Word Ptr SYS05_Para_RAM_Size,BX
Jnc C1606B ; Set the allocation flag
Jmp C1604B ; Go to the error condition
C1606B:
Mov Byte Ptr FLG16_Free_Memory,False
C1699B:
Ret
;
C1600B_Get_Free_Memory Endp
;
Page
;************************************************************************
;* *
;* C1700_CREATE_ESBX_TABLE *
;* *
;* This module creates the correct ES:BX addresses that are *
;* used when storing tracks read from the source diskette. *
;* The routine allocates at most 80 entries in the table for *
;* double sided diskettes. *
;* *
;************************************************************************
;
Public C1700_Create_ESBX_Table
;
C1700_Create_ESBX_Table Proc Near
;
C1701:
Mov Word Ptr WRK34_DMA_OverFlow_Counter,ZERO
;
Mov Word Ptr WRK18_Counter_ESBX_Entries,Zero
Mov AX,Nine ; Calculate DI = the number of bytes
Mov BX,Sector_Size ; per track and BX = the number of
Mul BX ; paragraphs per track
Mov DI,AX ; .
Mov BX,Paragraph_Size ; .
Mov DX,Zero ; .
Div BX ; .
Mov BX,AX ; ..End
;
Cmp Byte Ptr SYS19_Major_Vers_Number,Zero
Je C1702 ; Compare for PC DOS 1.0 and 1.1
Mov AX,Word Ptr SYS21_Alloc_Segment
Jmp C1703 ; Continue
C1702:
Mov AX,CS ; Calculate the address of the 1st
Mov CL,Four ; that will be copied into memory
Shl AX,CL ; .
Add AX,Offset MEM00_Bottom_Free_Memory
Shr AX,CL ; .
Inc AX ; ..End
C1703:
Mov SI,Offset MEM03_ESBX_Table
Mov Word Ptr [SI],Zero ; Put the 1st entry into the table
Mov Word Ptr [SI+Two],AX ; ..End
C1704:
Cmp Word Ptr WRK18_Counter_ESBX_Entries,Seventy_Nine
Jae C1707 ; Calculate the ES:BX valid entries
Add SI,Four ; Get the next ES:BX table address
;
Mov AX,[SI-Two] ; Check for DMA overflow error
And AX,DMA_Boundary_Mask ; .
Shl AX,CL ; .
Add AX,DI ; .
Jnc C1705 ; ..End
;
Mov AX,[SI-Two] ; Correction for DMA overflow
Add AX,BX ; .
Mov [SI-Two],AX ; ..End
Inc Word Ptr WRK34_DMA_Overflow_Counter
C1705:
Mov AX,[SI-Two] ; Increment the ES segment address
Add AX,BX ; ..End
C1706:
Mov Word Ptr [SI],Zero ; Put the address into the table
Mov Word Ptr [SI+Two],AX ; ..End
Inc Word Ptr WRK18_Counter_ESBX_Entries
Jmp C1704 ; Go back and find another entry
C1707:
Mov AX,Word Ptr SYS05_Para_RAM_Size
Mov DX,Zero ; Divide by the number of paragraphs
Div BX ; . per track
Mov Word Ptr WRK19_Number_ESBX_Entries,AX
Mov AX,Word Ptr WRK34_DMA_Overflow_Counter
Sub Word Ptr WRK19_Number_ESBX_Entries,AX
Cmp Word Ptr WRK19_Number_ESBX_Entries,Seventy_Nine
Jb C1799 ; If less than 79, continue
Mov Word Ptr WRK19_Number_ESBX_Entries,Seventy_Nine
Mov Byte Ptr FLG17_Copy_More_Disks,True
C1799:
Ret
;
C1700_Create_ESBX_Table Endp
;
Page
;************************************************************************
;* *
;* C1800_VALIDATE_SOURCE_DISK *
;* *
;* This module determines if the source diskette is readable *
;* and whether it was formatted under PC DOS 1.0, 1.1, 2.0 or *
;* 2.1. The routine also reads the first copy of the File *
;* Allocation Table (FAT) storing it for future comparisons *
;* as well as analyzing it first entry. *
;* *
;* A series of comparisons for the number of sectors per track *
;* is done for the following reasons. All diskettes formatted *
;* under PC DOS 2.0 and 2.1 really have nine sectors. In order *
;* to obtain an eight sectored diskette, the operating system *
;* sets the first byte of the File Allocation Table (FAT) *
;* accordingly. In contrast, PC DOS 1.0 and 1.1 formats a track *
;* to have exactly eight sectors. *
;* *
;************************************************************************
;
Public C1800_Validate_Source_Disk
;
C1800_Validate_Source_Disk Proc Near
;
C1801:
Mov Byte Ptr FLG08_Good_Read,True
;
Mov AL,Byte Ptr WRK01_Source_Drive
Mov Byte Ptr WRK06_Drive_Number,AL
Mov Byte Ptr WRK07_Head_Number,Zero
Mov Byte Ptr WRK08_Track_Number,Zero
Mov Byte Ptr WRK09_Sector_Number,Nine
Mov Byte Ptr WRK10_Number_of_Sectors,One
Push CS ; Establish the address ES:BX
Pop ES ; ..End
Mov BX,Offset MEM01_File_Allocation_Table
;
Call D1000_Read_Diskette
;
Cli ; Set the number of sectors to nine
Mov Byte Ptr SYS18_Disk_Parameter_Table[Four],Nine
Sti ; .
Mov Byte Ptr WRK17_Maximum_Sectors,Nine
;
Cmp Byte Ptr FLG08_Good_Read,True
Je C1803 ; Check for good read of sector nine
Cmp Byte Ptr WRK14_Status_Operation,Sector_Error
Je C1802 ; If so, continue
Mov Byte Ptr FLG15_IO_Error,One
Call D1200_Disk_IO_Error ; Process the error
Jmp C1899 ; ..End
C1802:
Cli ; Set the number of sectors to eight
Mov Byte Ptr SYS18_Disk_Parameter_Table[Four],Eight
Sti ; .
Mov Byte Ptr WRK17_Maximum_Sectors,Eight
C1803: ; .
Mov Byte Ptr FLG08_Good_Read,True
;
Mov AL,Byte Ptr WRK01_Source_Drive
Mov Byte Ptr WRK06_Drive_Number,AL
Mov Byte Ptr WRK07_Head_Number,Zero
Mov Byte Ptr WRK08_Track_Number,Zero
Mov Byte Ptr WRK09_Sector_Number,Two
Mov Byte Ptr WRK10_Number_of_Sectors,One
Push CS ; Establish the address ES:BX
Pop ES ; ..End
Mov BX,Offset MEM01_File_Allocation_Table
;
Call D1000_Read_Diskette
;
Cmp Byte Ptr FLG08_Good_Read,True
Je C1804 ; If the read operation was
; . successful, continue
Mov Byte Ptr FLG15_IO_Error,One
Call D1200_Disk_IO_Error ; Display appropriate error message
Jmp C1899 ; Go to the end of the module
C1804:
Mov AL,Byte Ptr MEM01_File_Allocation_Table[Zero]
;
Cmp AL,One_Side_Eight_Sectors
Jne C1805 ; If not, continue
Mov Byte Ptr WRK15_Maximum_Heads,Zero
Mov Byte Ptr WRK16_Maximum_Tracks,Thirty_Nine
Mov SI,Offset MES03_Copy81_Sectors
Jmp C1809 ; Continue the processing
C1805:
Cmp AL,Two_Sides_Eight_Sectors
Jne C1806 ; If not, continue
Mov Byte Ptr WRK15_Maximum_Heads,One
Mov Byte Ptr WRK16_Maximum_Tracks,Seventy_Nine
Mov SI,Offset MES04_Copy82_Sectors
Jmp C1809 ; Continue the processing
C1806:
Cmp AL,One_Side_Nine_Sectors
Jne C1807 ; If not, continue
Mov Byte Ptr WRK15_Maximum_Heads,Zero
Mov Byte Ptr WRK16_Maximum_Tracks,Thirty_Nine
Mov SI,Offset MES05_Copy91_Sectors
Jmp C1809 ; Continue the processing
C1807:
Cmp AL,Two_Sides_Nine_Sectors
Jne C1808 ; If not, continue
Mov Byte Ptr WRK15_Maximum_Heads,One
Mov Byte Ptr WRK16_Maximum_Tracks,Seventy_Nine
Mov SI,Offset MES06_Copy92_Sectors
Jmp C1809 ; Continue the processing
C1808:
Mov Byte Ptr FLG08_Good_Read,False
Mov SI,Offset MES19_Unrecoverable_Read
Call U1000_Display_Message ; Display the message on the screen
Mov SI,Offset MES90_Unknown_FAT_Error
Call U1000_Display_Message ; Display the message on the screen
Jmp C1899 ; Go to display the message
C1809:
Cmp Byte Ptr WRK15_Maximum_Heads,Zero
Je C1810 ; If the diskette is single sided,
; . display the diskette message
Cmp Byte Ptr FLG02_Double_Side,True
Je C1810 ; If the flag indicates to copy
; . both sides of the diskette,
; . then continue
Mov Byte Ptr WRK15_Maximum_Heads,Zero
Mov Byte Ptr WRK16_Maximum_Tracks,Thirty_Nine
C1810:
Mov AL,Byte Ptr WRK01_Source_Drive
Mov Byte Ptr WRK06_Drive_Number,AL
Mov Byte Ptr WRK07_Head_Number,One
Mov Byte Ptr WRK08_Track_Number,Zero
Mov Byte Ptr WRK09_Sector_Number,One
Mov Byte Ptr WRK10_Number_of_Sectors,One
Push CS ; Establish the ES segment register
Pop ES ; .
Push ES ; ..End
Mov BX,Offset MEM00_Bottom_Free_Memory
Cmp SYS19_Major_Vers_Number,Zero
Je C1811 ; If PC DOS 1.0 or 1.1, continue;
; . otherwise, setup ES:BX a little
Mov ES,Word Ptr SYS21_Alloc_Segment
Mov BX,Zero ; . differently
C1811:
Call D1000_Read_Diskette
Pop ES ; Restore ES in any case
;
Cmp Byte Ptr FLG08_Good_Read,True
Je C1813 ; Go to display the message
Cmp Byte Ptr WRK15_Maximum_Heads,One
Je C1812 ; If double sided diskette, error!!!
Mov Byte Ptr FLG08_Good_Read,True
Mov Byte Ptr FLG02_Double_Side,False
Jmp C1813 ; Display the appropriate message
C1812:
Mov SI,Offset MES19_Unrecoverable_Read
Call U1000_Display_Message ; Display the message on the screen
Mov SI,Offset MES91_Single_Side_Error
Call U1000_Display_Message ; Display the message on the screen
Jmp C1899 ; Go to the end of the module
C1813:
Call U1000_Display_Message ; Display the message on the screen
C1899:
Ret
;
C1800_Validate_Source_Disk Endp
;
Page
;************************************************************************
;* *
;* C1900_CREATE_CHRN_TABLE *
;* *
;* This module creates the CHRN table to be used in case the *
;* target diskette needs to be formatted. The abbreviation *
;* stands for C = track number, H = head number, R = sector *
;* number and N = a code for the number of bytes per sector. *
;* *
;************************************************************************
;
Public C1900_Create_CHRN_Table
;
C1900_Create_CHRN_Table Proc Near
;
C1901:
Mov BH,Byte Ptr WRK15_Maximum_Heads
Mov BL,Byte Ptr WRK16_Maximum_Tracks
Mov AL,Nine
;
Mov CL,BH ; Establish correct track number
Shr BL,CL ; ..End
;
Mov DL,Two ; . DL = number of sectors
Mov DH,Zero ; . DH = head number
Mov CH,Zero ; . CH = track number
Mov CL,One ; . CL = sector number
Mov SI,Offset MEM02_CHRN_Table; Set up initial registers
C1902:
Mov [SI],CH ; Establish an entry in the CHRN
Mov [SI+One],DH ; . table
Mov [SI+Two],CL ; .
Mov [SI+Three],DL ; ..End
;
Add SI,Four ; Get the addr of next CHRN entry
Inc CL ; Increment the sector number
Cmp CL,AL ; Compare for maximum sectors
Jbe C1902 ; If not, go back and try again
;
Mov CL,One ; Initialize sector number
Inc DH ; Increment the head number
Cmp DH,BH ; Compare for maximum heads
Jbe C1902 ; If not, go back and try again
;
Mov CL,One ; Initialize sector number
Mov DH,Zero ; Initialize head number
Inc CH ; Increment the track number
Cmp CH,BL ; Compare for maximum tracks
Jbe C1902 ; If not, go back and try again
C1999:
Ret
;
C1900_Create_CHRN_Table Endp
;
Page
;************************************************************************
;* *
;* C2000_READ_SOURCE_DISK *
;* *
;* This module reads a diskette track by track until it fills *
;* all of available memory specified by the ES:BX table. The *
;* processing sequence is: *
;* *
;* 1. Initializes the SI resgister to point to the correct entry *
;* in the ES:BX table. *
;* *
;* 2. Prints the initial read message on the screen. *
;* *
;* 3. Compares for the end of the ES:BX table and/or the number *
;* of tracks on the diskette. If not, continue. If so, *
;* return to B1100_Detail_Processing. *
;* *
;* 4. Reads a track from the source diskette. *
;* *
;* 5. Displays the track and head numbers on the screen. *
;* *
;* 6. Transfers control to 3. *
;* *
;************************************************************************
;
Page
;
Public C2000_Read_Source_Disk
;
C2000_Read_Source_Disk Proc Near
;
C2001:
Mov Byte Ptr FLG08_Good_Read,True
;
Mov SI,Offset MEM03_ESBX_Table
Mov Word Ptr WRK18_Counter_ESBX_Entries,Zero
;
Cmp Byte Ptr FLG13_First_Read_Write,False
Je C2002 ; If not first time, continue
Mov Byte Ptr WRK31_Track_Read_Counter,Zero
Jmp C2003 ; Go to display the message
C2002:
Cmp Byte Ptr FLG04_Single_Drive,False
Je C2004 ; If double drive copy, continue
C2003:
Push SI ; Save SI = Addr of ES:BX table
Mov SI,Offset MES97_Return_Linefeed
Call U1000_Display_Message ; Display a return and linefeed
Mov SI,Offset MES17_Reading_Track
Mov AL,Byte Ptr WRK21_Current_Source_Track
Call U1300_Convert_Binary_to_ASCII
Mov [SI+Fifteen],AX ; Put the track number into message
Mov AL,Byte Ptr WRK20_Current_Source_Head
Call U1300_Convert_Binary_to_ASCII
Mov [SI+Twenty_Five],AL ; Put the head number into message
Call U1000_Display_Message ; Display the message on the screeen
;
Mov AH,Read_Cursor_Command ; Get the current cursor position
Mov BH,Byte Ptr SYS03_Active_Page
Int Video_Interrupt ; ..End
;
Dec DH ; Save the row of the read track and
Mov Byte Ptr WRK24_Read_Message_Row,DH; . head message
;
Pop SI ; Restore SI = Addr of ES:BX table
C2004:
Mov AL,Byte Ptr WRK31_Track_Read_Counter
Cmp AL,Byte Ptr WRK16_Maximum_Tracks
Jbe C2005 ; If more tracks, then continue
Jmp C2099 ; Go to the end of the module
C2005:
Mov AX,Word Ptr WRK18_Counter_ESBX_Entries
Cmp AX,Word Ptr WRK19_Number_ESBX_Entries
Jbe C2006 ; If more memory exists, continue
Jmp C2099 ; Go to the end of the module
C2006:
; ; Display the current track and head
Mov AL,Byte Ptr WRK24_Read_Message_Row
Mov Byte Ptr WRK28_Current_Message_Row,AL
Mov AL,Byte Ptr WRK20_Current_Source_Head
Mov Byte Ptr WRK29_Current_Head,AL
Mov AL,Byte Ptr WRK21_Current_Source_Track
Mov Byte Ptr WRK30_Current_Track,AL
;
Call U1400_Display_Head_and_Track
;
; Establish the disk parameters
Mov AL,Byte Ptr WRK01_Source_Drive
Mov Byte Ptr WRK06_Drive_Number,AL
Mov AL,Byte Ptr WRK20_Current_Source_Head
Mov Byte Ptr WRK07_Head_Number,AL
Mov AL,Byte Ptr WRK21_Current_Source_Track
Mov Byte Ptr WRK08_Track_Number,AL
Mov Byte Ptr WRK09_Sector_Number,One
Mov AL,Byte Ptr WRK17_Maximum_Sectors
Mov Byte Ptr WRK10_Number_of_Sectors,AL
Mov AX,DS:[SI] ; .
Mov BX,AX ; .
Mov AX,DS:[SI+Two] ; .
Mov ES,AX ; ..End
;
Call D1000_Read_Diskette ; Read the source diskette
C2007:
Cmp Byte Ptr FLG08_Good_Read,True
Je C2008 ; If the read operation was
; . successful, then continue
Mov Byte Ptr FLG15_IO_Error,One
Call D1200_Disk_IO_Error ; Display appropriate error message
Jmp C2099 ; Go to the end of the module
C2008:
Inc Byte Ptr WRK31_Track_Read_Counter
Inc Word Ptr WRK18_Counter_ESBX_Entries
Add SI,Four ; Increment addr of the ES:BX table
Cmp Byte Ptr FLG02_Double_Side,False
Je C2009 ; If single sided, then continue
Inc Byte Ptr WRK20_Current_Source_Head
Cmp Byte Ptr WRK20_Current_Source_Head,One
Jbe C2010 ; If the head number is less than or
; . equal to one, then continue
Mov Byte Ptr WRK20_Current_Source_Head,Zero
C2009:
Inc Byte Ptr WRK21_Current_Source_Track
C2010:
Jmp C2004 ; Go back and read another track
C2099:
Ret
;
C2000_Read_Source_Disk Endp
;
Page
;************************************************************************
;* *
;* C2100_WRITE_FORMAT_TARGET_DISK *
;* *
;* This module formats and writes a diskette track by track *
;* until it fills all of available memory specified by the *
;* ES:BX table. The processing sequence is: *
;* *
;* 1. Initializes the SI resgister to point to the correct entry *
;* in the ES:BX table. *
;* *
;* 2. Prints the initial write message on the screen. *
;* *
;* 3. Compares for the end of the ES:BX table and/or the number *
;* of tracks on the diskette. If not, continue. If so, *
;* return to B1100_Detail_Processing. *
;* *
;* 4. Writes a track from the source diskette. *
;* *
;* 5. Displays the track and head numbers on the screen. *
;* *
;* 6. Transfers control to 3. *
;* *
;************************************************************************
;
Public C2100_Write_Format_Target_Disk
;
C2100_Write_Format_Target_Disk Proc Near
;
C2101:
Mov Byte Ptr FLG09_Good_Write,True
Mov Byte Ptr FLG11_Good_Format,True
;
Mov Byte Ptr WRK13_Retry_Counter,Number_of_Retries
;
Mov SI,Offset MEM03_ESBX_Table
Mov Word Ptr WRK18_Counter_ESBX_Entries,Zero
;
Cmp Byte Ptr FLG13_First_Read_Write,False
Je C2102 ; If not first time, continue
Mov Byte Ptr WRK32_Track_Write_Counter,Zero
Jmp C2103 ; Go to display the message
C2102:
Cmp Byte Ptr FLG04_Single_Drive,False
Je C2104 ; If double drive copy, continue
C2103:
Push SI ; Save SI = Addr of ES:BX table
;
Mov SI,Offset MES97_Return_Linefeed
Call U1000_Display_Message ; Display return and line feed
Mov SI,Offset MES23_Writing_Track
Call U1000_Display_Message ; Display write track message
;
Mov AH,Read_Cursor_Command ; Get the current cursor position
Mov BH,Byte Ptr SYS03_Active_Page
Int Video_Interrupt ; ..End
;
Dec DH ; Save the row of the I/O track and
Mov Byte Ptr WRK27_Write_Message_Row,DH; . head information
Sub DH,Two ; .
Mov Byte Ptr WRK24_Read_Message_Row,DH
;
Pop SI ; Restore SI = Addr of ES:BX table
C2104:
Mov AL,Byte Ptr WRK32_Track_Write_Counter
Cmp AL,Byte Ptr WRK16_Maximum_Tracks
Jbe C2105 ; If more tracks, then continue
Mov Byte Ptr FLG14_Copy_Complete,True
Jmp C2199 ; Go to the end of the module
C2105:
Mov AX,Word Ptr WRK18_Counter_ESBX_Entries
Cmp AX,Word Ptr WRK19_Number_ESBX_Entries
Jbe C2106 ; If more memory exists, continue
Jmp C2199 ; Go to the end of the module
C2106:
; ; Establish the disk parameters
Mov AL,Byte Ptr WRK02_Target_Drive
Mov Byte Ptr WRK06_Drive_Number,AL
Mov AL,Byte Ptr WRK22_Current_Target_Head
Mov Byte Ptr WRK07_Head_Number,AL
Mov AL,Byte Ptr WRK23_Current_Target_Track
Mov Byte Ptr WRK08_Track_Number,AL
Mov Byte Ptr WRK09_Sector_Number,One
Mov AL,Byte Ptr WRK17_Maximum_Sectors
Mov Byte Ptr WRK10_Number_of_Sectors,AL
Mov AX,DS:[SI+Two] ; .
Mov Word Ptr WRK11_Segment_Address,AX
Mov AX,DS:[SI] ; .
Mov Word Ptr WRK12_Offset_Address,AX
;
Call D1100_Write_Format_Diskette
;
Cmp Byte Ptr FLG11_Good_Format,True
Je C2107 ; If a good format, continue
Cmp Byte Ptr FLG09_Good_Write,True
Je C2107 ; If a good write, continue
Call D1200_Disk_IO_Error ; Display appropriate error message
Jmp C2199 ; Go to the end of the module
C2107:
Inc Byte Ptr WRK32_Track_Write_Counter
Inc Word Ptr WRK18_Counter_ESBX_Entries
Add SI,Four ; Increment addr of the ES:BX table
Cmp Byte Ptr FLG02_Double_Side,False
Je C2108 ; If single sided, then continue
Inc Byte Ptr WRK22_Current_Target_Head
Cmp Byte Ptr WRK22_Current_Target_Head,One
Jbe C2109 ; If the head number is less than or
; . equal to one, then continue
Mov Byte Ptr WRK22_Current_Target_Head,Zero
C2108:
Inc Byte Ptr WRK23_Current_Target_Track
C2109:
Jmp C2104 ; Go back and write another track
C2199:
Ret
;
C2100_Write_Format_Target_Disk Endp
;
Page
;************************************************************************
;* *
;* C2200_CHECK_FILE_ALLOC_TABLE *
;* *
;* This module checks the File Allocation Table (FAT) of the *
;* diskette in the source drive and compares it with the File *
;* Allocation Table (FAT) of the original source diskette. If *
;* there are any differences, the program sets the flag *
;* FLG12_Good_FAT to False; otherwise, the flag is True. *
;* *
;************************************************************************
;
Public C2200_Check_File_Alloc_Table
;
C2200_Check_File_Alloc_Table Proc Near
;
C2201:
Mov Byte Ptr FLG12_Good_FAT,True
;
Mov AL,Byte Ptr WRK01_Source_Drive
Mov Byte Ptr WRK06_Drive_Number,AL
Mov Byte Ptr WRK07_Head_Number,Zero
Mov Byte Ptr WRK08_Track_Number,Zero
Mov Byte Ptr WRK09_Sector_Number,Two
Mov Byte Ptr WRK10_Number_of_Sectors,One
Push CS ; Establish the ES segment register
Pop ES ; .
Push ES ; ..End
Mov BX,Offset MEM00_Bottom_Free_Memory
Cmp SYS19_Major_Vers_Number,Zero
Je C2202 ; If PC DOS 1.0 or 1.1, continue;
; . otherwise, set up ES:BX a little
Mov ES,Word Ptr SYS21_Alloc_Segment
Mov BX,Zero ; . differently
C2202:
Call D1000_Read_Diskette ; Read the File Allocation Table
Pop ES ; Restore ES in any case
;
Cmp Byte Ptr FLG08_Good_Read,True
Je C2203 ; If the read operation was
; . successful, continue
Mov Byte Ptr FLG15_IO_Error,One
Call D1200_Disk_IO_Error ; Display appropriate error message
Jmp C2299 ; Go to the end of the module
C2203:
Mov SI,Offset MEM01_File_Allocation_Table
Mov DI,Offset MEM00_Bottom_Free_Memory
Push ES ; Save ES for a moment
Cmp Byte Ptr SYS19_Major_Vers_Number,Zero
Je C2204 ; If PC DOS 1.0 or 1.1, continue
Mov ES,Word Ptr SYS21_Alloc_Segment
Mov DI,Zero ; Set up ES:DI for PC DOS 2.0+
C2204:
Mov CX,Sector_Size ; Set counter CX to compare the
; . sector size in words
Shr CX,1 ; ..End
Cld ; Clear the direction flag
Rep Cmpsw ; Compare all of the 512 bytes
Jne C2205 ; If there is a discrepancy, go to
; . the error message routine
Jmp C2206 ; Go to the end of the module
C2205:
Pop ES ; Restore the ES register
Mov Byte Ptr FLG12_Good_FAT,False
Mov SI,Offset MES19_Unrecoverable_Read
Call U1000_Display_Message ; Display the message on the screen
Mov SI,Offset MES90_Unknown_FAT_Error
Call U1000_Display_Message ; Display the message on the screen
Jmp C2299 ; Go to the end of the module
C2206:
Pop ES ; Restore the ES register
C2299:
Ret
;
C2200_Check_File_Alloc_Table Endp
;
Page
;************************************************************************
;* *
;* C2300_FREE_MEMORY *
;* *
;* This module free up allocated memory, provided that a user *
;* is running PC DOS 2.0 or greater; otherwise, it does nothing. *
;* *
;************************************************************************
;
Public C2300_Free_Memory
;
C2300_Free_Memory Proc Near
;
C2301:
Cmp Byte Ptr SYS19_Major_Vers_Number,Zero
Je C2399 ; If PC DOS 1.0 or 1.1, go to the
; . end of the module
Cmp Byte Ptr FLG16_Free_Memory,True
Je C2399 ; If memory was not allocated, go
; . to the end of the module
;
Mov AH,Free_Memory ; Free allocated memory
Push ES ; .
Mov ES,Word Ptr SYS21_Alloc_Segment
Int PC_DOS_Interrupt ; .
Pop ES ; .
Jnc C2399 ; ..End
;
Mov SI,Offset MES97_Return_Linefeed
Call U1000_Display_Message ; Issue a carriage return/linefeed
Mov SI,Offset MES99_Memory_Block_Destroyed
Call U1000_Display_Message ; Display the message on the screen
C2399:
Ret
;
C2300_Free_Memory Endp
;
Page
;************************************************************************
;* *
;* D1000_READ_DISKETTE *
;* *
;* This module reads a track at a time from a diskette. If it *
;* fails to read the diskette it tries Number_of_Retries = 5 *
;* times. *
;* *
;************************************************************************
;
Public D1000_Read_Diskette
;
D1000_Read_Diskette Proc Near
;
D1001:
Mov Byte Ptr WRK13_Retry_Counter,Number_of_Retries
D1002:
Clc ; Clear the carry flag
Mov AH,Read_Command ; Read the data on the diskette
Mov DL,Byte Ptr WRK06_Drive_Number
Mov DH,Byte Ptr WRK07_Head_Number
Mov CH,Byte Ptr WRK08_Track_Number
Mov CL,Byte Ptr WRK09_Sector_Number
Mov AL,Byte Ptr WRK10_Number_of_Sectors
Int Disk_Interrupt ; ..End
;
Mov Byte Ptr WRK14_Status_Operation,AH
Jnc D1099 ; Go to the end of the module
D1003:
Dec Byte Ptr WRK13_Retry_Counter
Jz D1004 ; Could not read the diskette
Clc ; Clear the carry flag
Mov AH,Reset_Command ; Initialize the disk controller
Int Disk_Interrupt ; .
Mov Byte Ptr WRK14_Status_Operation,AH
Jnc D1002 ; .
Jmp D1003 ; ..End
D1004:
Mov Byte Ptr FLG08_Good_Read,False
D1099:
Ret
;
D1000_Read_Diskette Endp
;
Page
;************************************************************************
;* *
;* D1100_WRITE_FORMAT_DISKETTE *
;* *
;* This module formats and writes a track at a time to a *
;* diskette. If it fails to format or a write a track, it tries *
;* Number_of_Retries = 5 times. *
;* *
;************************************************************************
;
Public D1100_Write_Format_Diskette
;
D1100_Write_Format_Diskette Proc Near
;
D1101:
Mov Byte Ptr WRK13_Retry_Counter,Number_of_Retries
D1102:
Clc ; Clear the carry flag
Mov AH,Format_Command ; Format the diskette
Mov DL,Byte Ptr WRK06_Drive_Number
Mov DH,Byte Ptr WRK07_Head_Number
Mov CH,Byte Ptr WRK08_Track_Number
Mov CL,Byte Ptr WRK09_Sector_Number
Mov AL,Byte Ptr WRK10_Number_of_Sectors
Push CS ; .
Pop ES ; .
Mov BX,Word Ptr WRK33_CHRN_Table_Address
Int Disk_Interrupt ; ..End
Mov Byte Ptr WRK14_Status_Operation,AH
Jnc D1105 ; Formatted the diskette
D1103:
Dec Byte Ptr WRK13_Retry_Counter
Jz D1104 ; Go to format error processing
Clc ; Clear the carry flag
Mov AH,Reset_Command ; Initialize the disk controller
Int Disk_Interrupt ; .
Mov Byte Ptr WRK14_Status_Operation,AH
Jnc D1102 ; Try to format the disk again
Jmp D1103 ; Try to initialize the disk again
D1104:
Mov Byte Ptr FLG15_IO_Error,Zero
Mov Byte Ptr FLG11_Good_Format,False
Jmp D1199 ; Go to the end of the module
D1105:
Mov Byte Ptr WRK13_Retry_Counter,Number_of_Retries
D1106:
Clc ; Clear the carry flag
Mov AH,Write_Command ; Write the diskette
Mov ES,Word Ptr WRK11_Segment_Address
Mov BX,Word Ptr WRK12_Offset_Address
Mov AL,Byte Ptr WRK10_Number_of_Sectors
Int Disk_Interrupt ; .
Mov Byte Ptr WRK14_Status_Operation,AH
Jnc D1109 ; ..End
D1107:
Dec Byte Ptr WRK13_Retry_Counter
Jz D1108 ; Go to write error processing
Clc ; Clear the carry flag
Mov AH,Reset_Command ; Initialize the disk controller
Int Disk_Interrupt ; .
Mov Byte Ptr WRK14_Status_Operation,AH
Jnc D1106 ; .
Jmp D1107 ; ..End
D1108:
Mov Byte Ptr FLG15_IO_Error,Two
Mov Byte Ptr FLG09_Good_Write,False
Jmp D1199 ; Go to the end of the module
D1109:
Add Word Ptr WRK33_CHRN_Table_Address,Thirty_Six
;
Mov AL,Byte Ptr WRK27_Write_Message_Row
Mov Byte Ptr WRK28_Current_Message_Row,AL
Mov AL,Byte Ptr WRK22_Current_Target_Head
Mov Byte Ptr WRK29_Current_Head,AL
Mov AL,Byte Ptr WRK23_Current_Target_Track
Mov Byte Ptr WRK30_Current_Track,AL
Call U1400_Display_Head_and_Track
D1199:
Ret
;
D1100_Write_Format_Diskette Endp
;
Page
;************************************************************************
;* *
;* D1200_DISK_IO_ERROR *
;* *
;* This module fans out a disk error. It tells a user if it *
;* occured on a read, format or write operation. If it cannot *
;* determine the nature of the error, the routine displays an *
;* unknown disk error message. *
;* *
;************************************************************************
;
Public D1200_Disk_IO_Error
;
D1200_Disk_IO_Error Proc Near
;
D1201:
Cmp Byte Ptr WRK14_Status_Operation,Time_Out_Error
Jne D1202 ; If not time out error, continue
Mov SI,Offset MES08_Drive_Not_Ready
Mov AL,Byte Ptr WRK06_Drive_Number
Add AL,Capital_Letter_A ; Convert drive number to a letter
Mov [SI+Twenty_Four],AL ; Put the drive letter into position
Call U1000_Display_Message
Jmp D1299 ; Go to the end of the module
D1202:
Cmp Byte Ptr FLG15_IO_Error,Zero
Jne D1203 ; If not a format error, continue
Mov SI,Offset MES18_Unrecoverable_Format
Jmp D1206 ; Continue processing
D1203:
Cmp Byte Ptr FLG15_IO_Error,One
Jne D1204 ; If not a read error, continue
Mov SI,Offset MES19_Unrecoverable_Read
Jmp D1206 ; Continue processing
D1204:
Cmp Byte Ptr FLG15_IO_Error,Two
Jne D1205 ; If not a write error, continue
Mov SI,Offset MES21_Unrecoverable_Write
Jmp D1206 ; Continue processing
D1205:
Mov SI,Offset MES22_Unrecoverable_IO
D1206:
Call U1000_Display_Message ; Display the message on the screen
D1207:
Cmp Byte Ptr WRK14_Status_Operation,Seek_Error
Jne D1208 ; If not a seek error, continue
Mov SI,Offset MES80_Seek_Error
Jmp D1217 ; Continue processing
D1208:
Cmp Byte Ptr WRK14_Status_Operation,Controller_Error
Jne D1209 ; If not a controller error, continue
Mov SI,Offset MES81_Controller_Error
Jmp D1217 ; Continue processing
D1209:
Cmp Byte Ptr WRK14_Status_Operation,CRC_Error
Jne D1210 ; If not a CRC error, continue
Mov SI,Offset MES82_CRC_Error
Jmp D1217 ; Continue processing
D1210:
Cmp Byte Ptr WRK14_Status_Operation,DMA_Boundary_Error
Jne D1211 ; If not DMA boundary error, continue
Mov SI,Offset MES83_DMA_Boundary_Error
Jmp D1217 ; Continue processing
D1211:
Cmp Byte Ptr WRK14_Status_Operation,DMA_Error
Jne D1212 ; If not a DMA error, continue
Mov SI,Offset MES84_DMA_Error
Jmp D1217 ; Continue processing
D1212:
Cmp Byte Ptr WRK14_Status_Operation,Sector_Error
Jne D1213 ; If not a sector error, continue
Mov SI,Offset MES85_Sector_Error
Jmp D1217 ; Continue processing
D1213:
Cmp Byte Ptr WRK14_Status_Operation,Write_Protect_Error
Jne D1214 ; If not write protected, continue
Mov SI,Offset MES86_Write_Protect_Error
Jmp D1217 ; Continue processing
D1214:
Cmp Byte Ptr WRK14_Status_Operation,Address_Mark_Error
Jne D1215 ; If not addr mark error, continue
Mov SI,Offset MES87_Address_Mark_Error
Jmp D1217 ; Continue processing
D1215:
Cmp Byte Ptr WRK14_Status_Operation,Command_Error
Jne D1216 ; If not a command error, continue
Mov SI,Offset MES88_Command_Error
Jmp D1217 ; Continue processing
D1216:
Mov SI,Offset MES89_Unknown_Error
D1217:
Call U1000_Display_Message ; Display the message on the screen
D1299:
Ret
;
D1200_Disk_IO_Error Endp
;
Page
;************************************************************************
;* *
;* S1000_SETUP_DISK_PARAM_TABLE *
;* *
;* This module sets up the Disk Parameter Table (Int 1EH) so that *
;* it points to the disk parameters for PC DOS 2.1 contained in *
;* this program. *
;* *
;************************************************************************
;
Public S1000_Setup_Disk_Param_Table
;
S1000_Setup_Disk_Param_Table Proc Near
;
S1001:
Push AX ; Save the registers
Push BX ; .
Push DS ; ..End
;
Cli ; Turn off the interrupts
;
Sub AX,AX ; Initialize DS to Absolute Zero
Mov DS,AX ; ..End
;
Mov BX,Disk_Parameter_Addr ; Save and redirect the address
Mov AX,[BX] ; .
Mov Word Ptr CS:SYS16_Save_DPT_Offset,AX
Mov AX,[BX+Two] ; .
Mov Word Ptr CS:SYS17_Save_DPT_Segment,AX
; .
Mov AX,Offset SYS18_Disk_Parameter_Table
Mov [BX],AX ; .
Mov AX,CS ; .
Mov [BX+Two],AX ; ..End
;
Sti ; Turn on interrupts
;
Pop DS ; Restore the registers
Pop BX ; .
Pop AX ; ..End
S1099:
Ret
;
S1000_Setup_Disk_Param_Table Endp
;
Page
;************************************************************************
;* *
;* S1100_RESTORE_DISK_PARAM_TABLE *
;* *
;* This module restores the Disk Parameter Table to its original *
;* address in PC DOS. *
;* *
;************************************************************************
;
Public S1100_Restore_Disk_Param_Table
;
S1100_Restore_Disk_Param_Table Proc Near
;
S1101:
Push AX ; Save the registers
Push BX ; .
Push DS ; ..End
;
Cli ; Turn off the interrupts
;
Sub AX,AX ; Initialize DS to Absolute Zero
Mov DS,AX ; ..End
;
Mov BX,Disk_Parameter_Addr ; Restore Disk Parameter Address
Mov AX,Word Ptr CS:SYS16_Save_DPT_Offset
Mov [BX],AX ; .
Mov AX,Word Ptr CS:SYS17_Save_DPT_Segment
Mov [BX+Two],AX ; ..End
;
Sti ; Turn on the interrupts
;
Pop DS ; Restore the registers
Pop BX ; .
Pop AX ; ..End
S1199:
Ret
;
S1100_Restore_Disk_Param_Table Endp
;
Page
;************************************************************************
;* *
;* S1200_GET_VERSION_NUMBER *
;* *
;* This module gets the current version number of PC DOS and *
;* stores the information in determining whether to allocate *
;* memory using the PC DOS 2.0 function calls. *
;* *
;************************************************************************
;
Public S1200_Get_Version_Number
;
S1200_Get_Version_Number Proc Near
;
S1201:
Push AX ; Save the registers and flags
Pushf ; ..End
;
Mov AH,Get_DOS_Version_Number
Int PC_DOS_Interrupt
Mov Byte Ptr SYS19_Major_Vers_Number,AL
Mov Byte Ptr SYS20_Minor_Vers_Number,AH
;
Popf ; Restore the registers and flags
Pop AX ; ..End
S1299:
Ret
;
S1200_Get_Version_Number Endp
;
Page
;************************************************************************
;* *
;* U1000_DISPLAY_MESSAGE *
;* *
;* This module displays a message on the screen. Before calling *
;* this module, the offset of the message should be in SI *
;* relative to the DS register. This routine preserves the *
;* registers and the flags. *
;* *
;************************************************************************
;
Public U1000_Display_Message
;
U1000_Display_Message Proc Near
;
U1001:
Push AX ; Save the registers and flags
Push BX ; .
Push SI ; .
Pushf ; ..End
U1002:
Mov AL,[SI] ; Put the character into AL
Cmp AL,EOT ; Compare for the end of the string
Je U1090 ; If so, go to end of the module
Mov AH,Write_TTY_Command ; Write the Character
Mov BH,Byte Ptr SYS03_Active_Page
Mov BL,Byte Ptr SYS04_Foreground_Color
Int Video_Interrupt ; ..End
Inc SI ; Increment the SI counter
Jmp U1002 ; Go back and try again
U1090:
Popf ; Restore the registers and flags
Pop SI ; .
Pop BX ; .
Pop AX ; ..End
U1099:
Ret
;
U1000_Display_Message Endp
;
Page
;************************************************************************
;* *
;* U1100_GET_RESPONSE *
;* *
;* This module gets the response from the keyboard and displays *
;* the information on the video display unit. The keyboard *
;* buffer is WRK05_Keyboard_Buffer. The first byte of this *
;* buffer contains the length of the buffer and must be less *
;* than or equal to 80 characters. The next 80 characters are *
;* the acutal buffer. The character EOT denotes the end of the *
;* buffer and can occur in any one of the 80 characters. *
;* *
;************************************************************************
;
Public U1100_Get_Response
;
U1100_Get_Response Proc Near
;
U1101:
Push AX ; Save the registers and flags
Push BX ; .
Push CX ; .
Push SI ; .
Pushf ; ..End
U1102:
Mov SI,Offset WRK05_Keyboard_Buffer+1
Mov CX,NUL ; Initialize the CX counter register
U1103:
Mov AH,Flush_Keyboard_Command; Read the character from keyboard
Mov AL,Read_Keyboard_Command; .
Int PC_DOS_Interrupt ; ..End
Cmp AL,ETX ; Compare for a control break
Jne U1104 ; If not, then continue
Mov SI,Offset MES98_Control_Break
Call U1000_Display_Message ; Display the message on the screen
Jmp A1002 ; Go to B1200_Final_Process
U1104:
Cmp Byte Ptr FLG05_Store_Buffer,True
Je U1105 ; If store keyboard entries, continue
Jmp U1190 ; If not, go to end of the module
U1105:
Cmp AL,BS ; Is AL a backspace character???
Jne U1106 ; If not, continue processing AL
Cmp CX,NUL ; Is the cursor at column zero????
Je U1103 ; Yes, so get another character
Dec CX ; Decrement CX to point to the
; . previous cursor location
Dec SI ; Decrement SI to go back to the
; . previos buffer location
;
Mov AH,Write_TTY_Command ; Write a backspace to the screen
Mov AL,BS ; .
Mov BH,Byte Ptr SYS03_Active_Page
Mov BL,Byte Ptr SYS04_Foreground_Color
Int Video_Interrupt ; ..End
;
Mov AH,Write_TTY_Command ; Write a space to the screen
Mov AL,Space ; .
Mov BH,Byte Ptr SYS03_Active_Page
Mov BL,Byte Ptr SYS04_Foreground_Color
Int Video_Interrupt ; ..End
;
Mov AH,Write_TTY_Command ; Write a backspace to the screen
Mov AL,BS ; .
Mov BH,Byte Ptr SYS03_Active_Page
Mov BL,Byte Ptr SYS04_Foreground_Color
Int Video_Interrupt ; ..End
;
Jmp U1103 ; Go back and get another character
U1106:
Cmp AL,CR ; Compare char for a carriage return
Je U1108 ; If so, insert an EOT into buffer
Cmp CX,Keyboard_Buffer_Size ; Check for keyboard buffer full
Jae U1107 ; If so, sound bell and get new char
Mov [SI],AL ; Put the character into the buffer
Inc SI ; Increment the keyboard address
Inc CX ; Increment the CX character counter
Jmp U1103 ; Go back and get another character
U1107:
Mov AH,Write_TTY_Command ; Sound the beep from the screen
Mov AL,Bell ; .
Mov BH,Byte Ptr SYS03_Active_Page
Mov BL,Byte Ptr SYS04_Foreground_Color
Int Video_Interrupt ; ..End
Jmp U1103 ; Go back and get another character
U1108:
Mov AL,EOT ; Put an EOT into the buffer
Mov [SI],AL ; ..End
;
Mov AH,Write_TTY_Command ; Write a carriage return to the
Mov AL,CR ; . screen
Mov BH,Byte Ptr SYS03_Active_Page
Mov BL,Byte Ptr SYS04_Foreground_Color
Int Video_Interrupt ; ..End
;
Mov AH,Write_TTY_Command ; Write a line feed to the screen
Mov AL,LF ; .
Mov BH,Byte Ptr SYS03_Active_Page
Mov BL,Byte Ptr SYS04_Foreground_Color
Int Video_Interrupt ; ..End
;
Mov WRK05_Keyboard_Buffer[0],CL; Set the length accrodingly
U1190:
Popf ; Restore the registers and flags
Pop SI ; .
Pop CX ; .
Pop BX ; .
Pop AX ; ..End
U1199:
Ret
U1100_Get_Response Endp
;
Page
;************************************************************************
;* *
;* U1200_GET_YES_OR_NO *
;* *
;* This module asks for a [Yy]es or [Nn]o answer from a user. The *
;* routine accepts only a [Yy] or [Nn] and exists with the flag *
;* FLG06_Yes_or_No set to True for YES and False for NO. *
;* *
;************************************************************************
;
Public U1200_Get_Yes_or_No
;
U1200_Get_Yes_or_No Proc Near
;
U1201:
Push AX ; Save the registers and flags
Push SI ; .
Pushf ; ..End
U1202:
Mov AH,Flush_Keyboard_Command; Read the character from keyboard
Mov AL,Read_Keyboard_Command; .
Int PC_DOS_Interrupt ; ..End
Cmp AL,ETX ; Compare for control break
Jne U1203 ; If not, then continue
Mov SI,Offset MES98_Control_Break
Call U1000_Display_Message ; Display the message on the screen
Jmp A1002 ; Go to B1200_Final_Process
U1203:
Cmp AL,Capital_Letter_Y ; Check for capital letter Y
Jne U1204 ; ..End
Mov Byte Ptr FLG06_Yes_or_No,True
Mov SI,Offset MES24_Yes ; Display YES on the screen
Call U1000_Display_Message ; ..End
Jmp U1290 ; Go to the end of the module
U1204:
Cmp AL,Small_Letter_y ; Check for small letter y
Jne U1205 ; ..End
Mov Byte Ptr FLG06_Yes_or_No,True
Mov SI,Offset MES24_Yes ; Display YES on the screen
Call U1000_Display_Message ; ..End
Jmp U1290 ; Go to the end of the module
U1205:
Cmp AL,Capital_Letter_N ; Check for capital letter N
Jne U1206 ; ..End
Mov Byte Ptr FLG06_Yes_or_No,False
Mov SI,Offset MES25_No ; Display NO on the screen
Call U1000_Display_Message ; ..End
Jmp U1290 ; Go to the end of the module
U1206:
Cmp AL,Small_Letter_n ; Check for small letter n
Jne U1207 ; ..End
Mov Byte Ptr FLG06_Yes_or_No,False
Mov SI,Offset MES25_No ; Display NO on the screen
Call U1000_Display_Message ; ..End
Jmp U1290 ; Go to the end of the module
U1207:
Jmp U1202 ; Go back and get another character
U1290:
Popf ; Restore the registers and flags
Pop SI ; .
Pop AX ; ..End
U1299:
Ret
;
U1200_Get_Yes_or_No Endp
;
Page
;************************************************************************
;* *
;* U1300_CONVERT_BINARY_TO_ASCII *
;* *
;* This module BCD contained in the AL register into an ASCII *
;* character. The output is returned in the AX register. *
;* *
;************************************************************************
;
Public U1300_Convert_Binary_to_ASCII
;
U1300_Convert_Binary_to_ASCII Proc Near
;
U1301:
Push DX ; Save the registers
Pushf ; ..End
;
Cbw ; Perform sign extension for division
Mov DL,Ten ; Set DL disvisor to 10D
Div DL ; Divide AL by 10D remainder in AH
Add AL,Zero_Digit ; Setup the characters in AL & AH
Add AH,Zero_Digit ; ..End
;
Popf ; Restore the registers
Pop DX ; ..End
U1399:
Ret
;
U1300_Convert_Binary_to_ASCII Endp
;
Page
;************************************************************************
;* *
;* U1400_DISPLAY_HEAD_AND_TRACK *
;* *
;* This module displays the current track and head number that *
;* is being read from the source diskette or written to the *
;* target diskette. *
;* *
;************************************************************************
;
Public U1400_Display_Head_and_Track
;
U1400_Display_Head_and_Track Proc Near
;
U1401:
Push AX ; Save the registers
Push BX ; .
Push DX ; .
Pushf ; ..End
;
Mov AH,Set_CPos_Command ; Set cursor to track position
Mov BH,Byte Ptr SYS03_Active_Page
Mov DH,Byte Ptr WRK28_Current_Message_Row
Mov DL,Fifteen ; .
Int Video_Interrupt ; ..End
;
; Write the current track number
Mov AL,Byte Ptr WRK30_Current_Track
Call U1300_Convert_Binary_to_ASCII
Push AX ; .
Mov AH,Write_TTY_Command ; .
Mov BH,Byte Ptr SYS03_Active_Page
Mov BL,Byte Ptr SYS04_Foreground_Color
Int Video_Interrupt ; .
Pop AX ; .
Mov AL,AH ; .
Mov AH,Write_TTY_Command ; .
Mov BH,Byte Ptr SYS03_Active_Page
Mov BL,Byte Ptr SYS04_Foreground_Color
Int Video_Interrupt ; ..End
;
Mov AH,Set_CPos_Command ; Set cursor to head position
Mov BH,Byte Ptr SYS03_Active_Page
Mov DH,Byte Ptr WRK28_Current_Message_Row
Mov DL,Twenty_Five ; .
Int Video_Interrupt ; ..End
; ; Write the current head number
Mov AL,Byte Ptr WRK29_Current_Head
Call U1300_Convert_Binary_to_ASCII
Mov AL,AH ;.
Mov AH,Write_TTY_Command ;.
Mov BH,Byte Ptr SYS03_Active_Page
Mov BL,Byte Ptr SYS04_Foreground_Color
Int Video_Interrupt ; ..End
;
Mov AH,Set_CPos_Command ; Set cursor to the next line
Mov BH,Byte Ptr SYS03_Active_Page
Mov DH,Byte Ptr WRK28_Current_Message_Row
Inc DH ; .
Mov DL,Zero ; .
Int Video_Interrupt ; ..End
U1490:
Popf ; Restore the registers
Pop DX ;
Pop BX ; .
Pop AX ; ..End
U1499:
Ret
;
U1400_Display_Head_and_Track Endp
;
Page
;************************************************************************
;* *
;* FLAGS *
;* *
;* This portion of FREECOPY contains the definitions of all of *
;* flags defined in the program. *
;* *
;************************************************************************
;
FLG01_Good_Command DB (?) ; Establishes any errors in the
; . command line entered by a user
FLG02_Double_Side DB (?) ; Points out whether the user wants
; . to copy only the top side of a
; . floppy diskette
FLG03_Default_Drive DB (?) ; Shows if the default drive is a
; . valid floppy disk drive
FLG04_Single_Drive DB (?) ; Determines if the machine is a
; . single drive system
FLG05_Store_Buffer DB (?) ; Establishes whether to put the
; . characters entered from the
; . keyboard into the buffer
FLG06_Yes_or_No DB (?) ; Points out the user's response
; . NO = False YES = True
FLG07_First_Time DB (?) ; Shows the number of times the user
; . copies a diskette
; . ONCE = True MORE = False
FLG08_Good_Read DB (?) ; Flags establish whether the
FLG09_Good_Write DB (?) ; . operation was performed correctly
FLG10_Good_Verify DB (?) ; . YES = True NO = False
FLG11_Good_Format DB (?) ; ..End
FLG12_Good_FAT DB (?) ; Establishes a good FAT when reading
; . source diskette more than once
FLG13_First_Read_Write DB (?) ; Shows if a diskette is being read
; . or written for the first time
; . YES = True NO = False
FLG14_Copy_Complete DB (?) ; Points out if a diskette has been
; . copied completely
; . YES = True NO = False
FLG15_IO_Error DB (?) ; Establishes the type of IO error
; . Zero = Format error
; . One = Read error
; . Two = Write error
; ..End
FLG16_Free_Memory DB (?) ; Determines whether memory should
; . using the PC DOS function calls
FLG17_Copy_More_Disks DB (?) ; Indicates whether to ask a user to
; . write the same disk over again
;
Page
;************************************************************************
;* *
;* MESSAGES *
;* *
;* This portion of FREECOPY contains the definitions of all of *
;* messages defined in the program. *
;* *
;************************************************************************
;
MES00_Copy_Notice Label Byte
DB CR,LF
DB 'FREECOPY Disk Utility',CR,LF
DB 'IBM Personal Computer/Jr.',CR,LF
DB 'Version 1.13 (C)Copyright 1984, 1985',CR,LF
DB CR,LF
DB 'Squire Buresh Assoc., Inc.',CR,LF
DB 'Post Office Box 112',CR,LF
DB 'Millbury, MA 01527',CR,LF
DB CR,LF
DB '$25.00 requested contribution.',CR,LF,EOT
MES01A_Write_Another_Diskette Label Byte
DB CR,LF
DB 'Write source diskette again (Y/N)? ',EOT
MES01B_Copy_Another_diskette Label Byte
DB CR,LF
DB 'Copy another diskette (Y/N)? ',EOT
MES02_Copy_Complete Label Byte
DB CR,LF
DB 'Copy complete.',CR,LF,EOT
MES03_Copy81_Sectors Label Byte
DB CR,LF
DB 'Copying 8 sectors per track, 1 side.',CR,LF,EOT
MES04_Copy82_Sectors Label Byte
DB CR,LF
DB 'Copying 8 sectors per track, 2 sides.',CR,LF,EOT
MES05_Copy91_Sectors Label Byte
DB CR,LF
DB 'Copying 9 sectors per track, 1 side.',CR,LF,EOT
MES06_Copy92_Sectors Label Byte
DB CR,LF
DB 'Copying 9 sectors per track, 2 sides.',CR,LF,EOT
MES07_Correct_And_Press_Key Label Byte
DB CR,LF
DB 'Correct, and press any key to continue',CR,LF,EOT
MES08_Drive_Not_Ready Label Byte
DB CR,LF
DB 'Diskette not in drive :.',CR,LF,EOT
MES09_Insert_Source Label Byte
DB CR,LF
DB 'Insert source diskette in drive :.',CR,LF,EOT
MES10_Insert_Target Label Byte
DB CR,LF
DB 'Insert target diskette in drive :.',CR,LF,EOT
MES11_Insufficient_Memory Label Byte
DB CR,LF
DB 'Insufficient memory.',Bell,CR,LF,EOT
MES12_Invalid_Parameter Label Byte
DB CR,LF
DB 'Invalid parameter(s) specified.',CR,LF,EOT
MES13_Invalid_Default Label Byte
DB CR,LF
DB 'Invalid default floppy disk drive',CR,LF,EOT
MES14_Invalid_Drive Label Byte
DB CR,LF
DB 'Invalid drive specification.',CR,LF,EOT
MES15_Single_Drive_Copy Label Byte
DB CR,LF
DB 'NOTE: Copying diskette on single drive.',Bell,CR,LF,EOT
MES16_Press_Any_Key Label Byte
DB CR,LF
DB 'Press any key when ready.',CR,LF,EOT
MES17_Reading_Track Label Byte
DB 'Reading track ( ) head ( ).',CR,LF,EOT
MES18_Unrecoverable_Format Label Byte
DB CR,LF
DB 'Unrecoverable format error on target.',CR,LF,EOT
MES19_Unrecoverable_Read Label Byte
DB CR,LF
DB 'Unrecoverable read error on source.',CR,LF,EOT
MES20_Unrecoverable_Verify Label Byte
DB CR,LF
DB 'Unrecoverable verify error on target.',CR,LF,EOT
MES21_Unrecoverable_Write Label Byte
DB CR,LF
DB 'Unrecoverable write error on target.',CR,LF,EOT
MES22_Unrecoverable_IO Label Byte
DB CR,LF
DB 'Unrecoverable IO error.',CR,LF,EOT
MES23_Writing_Track Label Byte
DB 'Writing track ( ) head ( ).',CR,LF,EOT
MES24_Yes Label Byte
DB 'YES',CR,LF,EOT
MES25_No Label Byte
DB 'NO',CR,LF,EOT
MES80_Seek_Error Label Byte
DB 'Seek operation has failed.',CR,LF,EOT
MES81_Controller_Error Label Byte
DB 'Disk controller has failed.',CR,LF,EOT
MES82_CRC_Error Label Byte
DB 'Cyclic redundancy check (CRC) error.',CR,LF,EOT
MES83_DMA_Boundary_Error Label Byte
DB 'Attempted to DMA across a 64K boundary.',CR,LF,EOT
MES84_DMA_Error Label Byte
DB 'DMA overrun on I/O operation.',CR,LF,EOT
MES85_Sector_Error Label Byte
DB 'Requested sector not found.',CR,LF,EOT
MES86_Write_Protect_Error Label Byte
DB 'Output diskette is write protected.',CR,LF,EOT
MES87_Address_Mark_Error Label Byte
DB 'Address mark was not found.',CR,LF,EOT
MES88_Command_Error Label Byte
DB 'Bad command passed to the disk interrupt 13H.',CR,LF,EOT
MES89_Unknown_Error Label Byte
DB 'Unknown diskette error encountered.',CR,LF,EOT
MES90_Unknown_FAT_Error Label Byte
DB 'First byte of the FAT does not',CR,LF
DB 'match any known diskette type.',CR,LF,EOT
MES91_Single_Side_Error Label byte
DB 'Double sided diskette in a',CR,LF
DB 'single sided disk drive.',CR,LF,EOT
MES97_Return_Linefeed Label Byte
DB CR,LF,EOT
MES98_Control_Break Label Byte
DB '^C',CR,LF,EOT
MES99_Memory_Block_Destroyed Label Byte
DB 'Memory control block destroyed.',CR,LF,EOT
MES100_Freecopy_Finished Label Byte
DB CR,LF
DB 'Returning to PC DOS.',CR,LF,EOT
;
Page
;************************************************************************
;* *
;* WORK VARIABLES *
;* *
;* This portion of FREECOPY contains the definitions of the work *
;* variables that are used by the program. *
;* *
;************************************************************************
;
WRK01_Source_Drive DB (?) ; Source diskette drive number
WRK02_Target_Drive DB (?) ; Target diskette drive number
WRK03_Valid_Filename DB 11 Dup (32D); Valid diskette file name
WRK04_Parameter_Count DB (?) ; Valid diskette filler area
;
WRK05_Keyboard_Buffer Label Byte
DB 80D ; Length of the keyboard buffer
DB 80 Dup (?); Actual keyboard buffer
DB EOT ; Last char denotes the end of text
;
WRK06_Drive_Number DB (?) ; Drive number of a disk drive
WRK07_Head_Number DB (?) ; Head number of a disk drive
WRK08_Track_Number DB (?) ; Track number of a diskette
WRK09_Sector_Number DB (?) ; Sector number of a diskette
WRK10_Number_of_Sectors DB (?) ; Number of sectors on a track
WRK11_Segment_Address DW (?) ; ES segment address
WRK12_Offset_Address DW (?) ; BX offset address
WRK13_Retry_Counter DB (?) ; Number of retrys to make
WRK14_Status_Operation DB (?) ; Result of the operation
;
WRK15_Maximum_Heads DB (?) ; Maximum heads, tracks and sectors
WRK16_Maximum_Tracks DB (?) ; .
WRK17_Maximum_Sectors DB (?) ; ..End
;
WRK18_Counter_ESBX_Entries DW (?) ; Counter to calculate ES:BX entries
WRK19_Number_ESBX_Entries DW (?) ; Maximum ES:BX table entires
;
Page
;************************************************************************
;* *
;* WORK VARIABLES Page 2 *
;* *
;************************************************************************
;
WRK20_Current_Source_Head DB (?) ; Current source head & track number
WRK21_Current_Source_Track DB (?) ; ..End
WRK22_Current_Target_Head DB (?) ; Current target head & track number
WRK23_Current_Target_Track DB (?) ; . End
;
WRK24_Read_Message_Row DB (?) ; Cursor row of read, verify, format
WRK25_Verify_Message_Row DB (?) ; and write message
WRK26_Format_Message_Row DB (?) ; .
WRK27_Write_Message_Row DB (?) ; .
WRK28_Current_Message_Row DB (?) ; ..End
;
WRK29_Current_Head DB (?) ; Current head and track to display
WRK30_Current_Track DB (?) ; . on the screen
;
WRK31_Track_Read_Counter DB (?) ; Counter of tracks processed
WRK32_Track_Write_Counter DB (?) ; ..End
;
WRK33_CHRN_Table_Address DW (?) ; Current address of the CHRN table
;
WRK34_DMA_Overflow_Counter DW (?) ; Counts how many times FREECOPY
; . adjusted for DMA overflow
;
Page
;************************************************************************
;* *
;* SYSTEM VARIABLES *
;* *
;* This portion of FREECOPY contains the definitions of all of *
;* the system variables used by the program. *
;* *
;************************************************************************
;
SYS01_Number_Columns DB (?) ; Number of columns in current mode
SYS02_Current_Mode DB (?) ; Current video mode
SYS03_Active_Page DB (?) ; Active display page
SYS04_Foreground_Color DB (?) ; Foreground color number
SYS05_Para_RAM_Size DW (?) ; Number of free 16 byte paragraphs
SYS06_Monitor_Flag DB (?) ; 0 = monochrome 1 = graphics
SYS07_No_Parallel_Ports DB (?) ; Number of parallel ports
SYS08_Game_Adapters DB (?) ; Number of RS-232 ports
SYS09_No_RS232_Ports DB (?) ; 0 = no adapter 1 = has adapter
SYS10_No_Disk_Drives DB (?) ; Number of floppy disk drives
SYS11_Init_Video_Mode DB (?) ; Initial video mode when powering
; up the machine
SYS12_Planar_RAM_Size DB (?) ; Planar RAM size
SYS13_IPL_From_Diskette DB (?) ; Location of initial program load
SYS14_Default_Drive DB (?) ; Default disk drive
;
SYS15_Stack_Pointer DW (?) ; Stack pointer value when entering
; . FREECOPY from PC DOS
SYS16_Save_DPT_Offset DW (?) ; Address of Disk Parameter Table
SYS17_Save_DPT_Segment DW (?) ; ..End
;
SYS18_Disk_Parameter_Table Label Byte
DB 11011111B ; SRT = 0D & Head Unload = 0FH
DB 002H ; Head Load = 1 Mode = DMA
DB 025H ; Wait to turn the motor off
DB 002H ; 512 bytes per sector
DB 009H ; 9 sectors per track
DB 02AH ; PC DOS gap length for I/O
DB 0FFH ; Data length parameter
DB 050H ; PC DOS gap length for format
DB 0F6H ; Fille byte for format
DB 00FH ; Head Settle time in milliseconds
DB 002H ; Motor start-up time (1/8 sec.)
;
SYS19_Major_Vers_Number DB (?) ; Major and minor version number
SYS20_Minor_Vers_Number DB (?) ; . of the operating system
;
SYS21_Alloc_Segment DW (?) ; Beginning segment address of
; . free memory
;
Page
;************************************************************************
;* *
;* SETUP STACK POINTER AND MEMORY *
;* *
;* This portion of FREECOPY is contains the stack and the label *
;* that indicates the beginning of available memory. *
;* *
;************************************************************************
;
MEM05_Bottom_of_the_Stack Label Word
DW 64 Dup (?)
MEM04_Top_of_the_Stack Label Word
;
MEM03_ESBX_Table Equ MEM04_Top_of_the_Stack+2
;
MEM02_CHRN_Table Equ MEM03_ESBX_Table+320
;
MEM01_File_Allocation_Table Equ MEM02_CHRN_Table+2880
;
MEM00_Bottom_Free_Memory Equ MEM01_File_Allocation_Table+512
;
Page
;************************************************************************
;* *
;* END OF THE PROGRAM *
;* *
;************************************************************************
;
CSEG Ends
End A1000_Main_Module